From 7037f6a1974ffa6aba617c8c614d81dd196adc73 Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 7 Apr 2019 15:22:09 +0800 Subject: [PATCH] Cover more ST Coroutine code --- trunk/src/app/srs_app_st.cpp | 24 ++++++++++++------------ trunk/src/app/srs_app_st.hpp | 4 ++++ trunk/src/utest/srs_utest_app.cpp | 21 +++++++++++++++++++++ 3 files changed, 37 insertions(+), 12 deletions(-) diff --git a/trunk/src/app/srs_app_st.cpp b/trunk/src/app/srs_app_st.cpp index 5907e323c..a7219f820 100755 --- a/trunk/src/app/srs_app_st.cpp +++ b/trunk/src/app/srs_app_st.cpp @@ -79,6 +79,8 @@ int SrsDummyCoroutine::cid() return 0; } +_ST_THREAD_CREATE_PFN _pfn_st_thread_create = (_ST_THREAD_CREATE_PFN)st_thread_create; + SrsSTCoroutine::SrsSTCoroutine(const string& n, ISrsCoroutineHandler* h, int cid) { name = n; @@ -114,7 +116,7 @@ srs_error_t SrsSTCoroutine::start() return err; } - if ((trd = (srs_thread_t)st_thread_create(pfn, this, 1, 0)) == NULL) { + if ((trd = (srs_thread_t)_pfn_st_thread_create(pfn, this, 1, 0)) == NULL) { err = srs_error_new(ERROR_ST_CREATE_CYCLE_THREAD, "create failed"); srs_freep(trd_err); @@ -136,21 +138,19 @@ void SrsSTCoroutine::stop() disposed = true; interrupt(); - - void* res = NULL; + // When not started, the rd is NULL. if (trd) { + void* res = NULL; int r0 = st_thread_join((st_thread_t)trd, &res); srs_assert(!r0); - } - - // Always override the error by the error from worker. - srs_error_t err_res = (srs_error_t)res; - if (err_res != srs_success && trd_err != err_res) { - srs_freep(trd_err); - // It's ok to directly use it, because it's returned by st_thread_join. - trd_err = err_res; - return; + + srs_error_t err_res = (srs_error_t)res; + if (err_res != srs_success) { + // When worker cycle done, the error has already been overrided, + // so the trd_err should be equal to err_res. + srs_assert(trd_err == err_res); + } } // If there's no error occur from worker, try to set to terminated error. diff --git a/trunk/src/app/srs_app_st.hpp b/trunk/src/app/srs_app_st.hpp index 5bdd92d6b..cc837ccd3 100644 --- a/trunk/src/app/srs_app_st.hpp +++ b/trunk/src/app/srs_app_st.hpp @@ -106,6 +106,10 @@ public: virtual int cid(); }; +// For utest to mock the thread create. +typedef void* (*_ST_THREAD_CREATE_PFN)(void *(*start)(void *arg), void *arg, int joinable, int stack_size); +extern _ST_THREAD_CREATE_PFN _pfn_st_thread_create; + /** * A ST-coroutine is a lightweight thread, just like the goroutine. * But the goroutine maybe run on different thread, while ST-coroutine only diff --git a/trunk/src/utest/srs_utest_app.cpp b/trunk/src/utest/srs_utest_app.cpp index 070fb9055..7a526296a 100644 --- a/trunk/src/utest/srs_utest_app.cpp +++ b/trunk/src/utest/srs_utest_app.cpp @@ -285,4 +285,25 @@ VOID TEST(AppCoroutineTest, Cycle) } } +void* mock_st_thread_create(void *(*/*start*/)(void *arg), void */*arg*/, int /*joinable*/, int /*stack_size*/) { + return NULL; +} + +VOID TEST(AppCoroutineTest, StartThread) +{ + MockCoroutineHandler ch; + SrsSTCoroutine sc("test", &ch); + ch.trd = ≻ + + _ST_THREAD_CREATE_PFN ov = _pfn_st_thread_create; + _pfn_st_thread_create = (_ST_THREAD_CREATE_PFN)mock_st_thread_create; + + srs_error_t err = sc.start(); + _pfn_st_thread_create = ov; + + EXPECT_TRUE(srs_success != err); + EXPECT_TRUE(ERROR_ST_CREATE_CYCLE_THREAD == srs_error_code(err)); + srs_freep(err); +} + #endif