From 1ce040cc2c8407e384aa8818c85c140398dbd8c1 Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 7 Apr 2019 14:35:11 +0800 Subject: [PATCH] Cover more ST Coroutine code --- trunk/src/app/srs_app_st.cpp | 11 +++++---- trunk/src/app/srs_app_st.hpp | 2 ++ trunk/src/utest/srs_utest_app.cpp | 37 +++++++++++++++++++++++++++++-- 3 files changed, 44 insertions(+), 6 deletions(-) diff --git a/trunk/src/app/srs_app_st.cpp b/trunk/src/app/srs_app_st.cpp index 34b33652f..5907e323c 100755 --- a/trunk/src/app/srs_app_st.cpp +++ b/trunk/src/app/srs_app_st.cpp @@ -86,7 +86,7 @@ SrsSTCoroutine::SrsSTCoroutine(const string& n, ISrsCoroutineHandler* h, int cid context = cid; trd = NULL; trd_err = srs_success; - started = interrupted = disposed = false; + started = interrupted = disposed = cycle_done = false; } SrsSTCoroutine::~SrsSTCoroutine() @@ -153,8 +153,8 @@ void SrsSTCoroutine::stop() return; } - // If there's no error occur from worker, try to set to interrupted error. - if (trd_err == srs_success) { + // If there's no error occur from worker, try to set to terminated error. + if (trd_err == srs_success && !cycle_done) { trd_err = srs_error_new(ERROR_THREAD_TERMINATED, "terminated"); } @@ -163,7 +163,7 @@ void SrsSTCoroutine::stop() void SrsSTCoroutine::interrupt() { - if (!started || interrupted) { + if (!started || interrupted || cycle_done) { return; } interrupted = true; @@ -199,6 +199,9 @@ srs_error_t SrsSTCoroutine::cycle() if (err != srs_success) { return srs_error_wrap(err, "coroutine cycle"); } + + // Set cycle done, no need to interrupt it. + cycle_done = true; return err; } diff --git a/trunk/src/app/srs_app_st.hpp b/trunk/src/app/srs_app_st.hpp index 8408a5465..5bdd92d6b 100644 --- a/trunk/src/app/srs_app_st.hpp +++ b/trunk/src/app/srs_app_st.hpp @@ -133,6 +133,8 @@ private: bool started; bool interrupted; bool disposed; + // Cycle done, no need to interrupt it. + bool cycle_done; public: // Create a thread with name n and handler h. // @remark User can specify a cid for thread to use, or we will allocate a new one. diff --git a/trunk/src/utest/srs_utest_app.cpp b/trunk/src/utest/srs_utest_app.cpp index ee52a349f..070fb9055 100644 --- a/trunk/src/utest/srs_utest_app.cpp +++ b/trunk/src/utest/srs_utest_app.cpp @@ -87,13 +87,18 @@ public: SrsSTCoroutine* trd; srs_error_t err; srs_cond_t running; + srs_cond_t exited; int cid; + // Quit without error. + bool quit; public: - MockCoroutineHandler() : trd(NULL), err(srs_success), cid(0) { + MockCoroutineHandler() : trd(NULL), err(srs_success), cid(0), quit(false) { running = srs_cond_new(); + exited = srs_cond_new(); } virtual ~MockCoroutineHandler() { srs_cond_destroy(running); + srs_cond_destroy(exited); } public: virtual srs_error_t cycle() { @@ -102,10 +107,12 @@ public: srs_cond_signal(running); cid = _srs_context->get_id(); - while ((r0 = trd->pull()) == srs_success && err == srs_success) { + while (!quit && (r0 = trd->pull()) == srs_success && err == srs_success) { srs_usleep(10 * 1000); } + srs_cond_signal(exited); + if (err != srs_success) { srs_freep(r0); return err; @@ -241,6 +248,9 @@ VOID TEST(AppCoroutineTest, Cycle) // Set cycle to error. ch.err = srs_error_new(-1, "cycle"); + // When thread terminated, thread will get its error. + srs_cond_timedwait(ch.exited, 100 * SRS_UTIME_MILLISECONDS); + // Override the error by cycle error. sc.stop(); @@ -250,6 +260,29 @@ VOID TEST(AppCoroutineTest, Cycle) EXPECT_TRUE(-1 == srs_error_code(err)); srs_freep(err); } + + if (true) { + MockCoroutineHandler ch; + SrsSTCoroutine sc("test", &ch); + ch.trd = ≻ + + EXPECT_TRUE(srs_success == sc.start()); + EXPECT_TRUE(srs_success == sc.pull()); + + // Quit without error. + ch.quit = true; + + // Wait for thread to done. + srs_cond_timedwait(ch.exited, 100 * SRS_UTIME_MILLISECONDS); + + // Override the error by cycle error. + sc.stop(); + + // Should be cycle error. + srs_error_t err = sc.pull(); + EXPECT_TRUE(srs_success == err); + srs_freep(err); + } } #endif