diff --git a/trunk/src/utest/srs_utest_rtc.cpp b/trunk/src/utest/srs_utest_rtc.cpp index b1da5accc..96bf960a6 100644 --- a/trunk/src/utest/srs_utest_rtc.cpp +++ b/trunk/src/utest/srs_utest_rtc.cpp @@ -41,6 +41,7 @@ VOID TEST(KernelRTCTest, ConnectionManagerTest) { srs_error_t err = srs_success; + // Normal scenario, free object by manager. if (true) { SrsConnectionManager manager; HELPER_EXPECT_SUCCESS(manager.start()); @@ -54,6 +55,38 @@ VOID TEST(KernelRTCTest, ConnectionManagerTest) srs_usleep(0); // Switch context for manager to dispose connections. EXPECT_EQ(0, manager.size()); EXPECT_TRUE(manager.empty()); } + + // Coroutine switch context, signal is lost. + if (true) { + SrsConnectionManager manager; + HELPER_EXPECT_SUCCESS(manager.start()); + EXPECT_EQ(0, manager.size()); EXPECT_TRUE(manager.empty()); + + if (true) { // First connection, which will switch context when deleting. + MockSrsConnection* conn = new MockSrsConnection(); + conn->do_switch = true; + manager.add(conn); + EXPECT_EQ(1, manager.size()); EXPECT_EQ(0, manager.zombies_.size()); + + manager.remove(conn); // Remove conn to zombies. + EXPECT_EQ(1, manager.size()); EXPECT_EQ(1, manager.zombies_.size()); + + srs_usleep(0); // Switch to manager coroutine to try to free zombies. + EXPECT_EQ(0, manager.size()); EXPECT_EQ(0, manager.zombies_.size()); + } + + if (true) { // Now the previous conn switch back to here, and lost the signal. + MockSrsConnection* conn = new MockSrsConnection(); + manager.add(conn); + EXPECT_EQ(1, manager.size()); EXPECT_EQ(0, manager.zombies_.size()); + + manager.remove(conn); // Remove conn to zombies, signal is lost. + EXPECT_EQ(1, manager.size()); EXPECT_EQ(1, manager.zombies_.size()); + + srs_usleep(0); // Switch to manager, but no signal is triggered before, so conn will be freed by loop. + EXPECT_EQ(0, manager.size()); EXPECT_EQ(0, manager.zombies_.size()); + } + } } VOID TEST(KernelRTCTest, StringDumpHexTest) diff --git a/trunk/src/utest/srs_utest_service.cpp b/trunk/src/utest/srs_utest_service.cpp index 7112cc2b0..7cace63cc 100644 --- a/trunk/src/utest/srs_utest_service.cpp +++ b/trunk/src/utest/srs_utest_service.cpp @@ -44,10 +44,14 @@ using namespace std; MockSrsConnection::MockSrsConnection() { + do_switch = false; } MockSrsConnection::~MockSrsConnection() { + if (do_switch) { + srs_usleep(0); + } } std::string MockSrsConnection::remote_ip() diff --git a/trunk/src/utest/srs_utest_service.hpp b/trunk/src/utest/srs_utest_service.hpp index 84aa9be7e..d60254a2b 100644 --- a/trunk/src/utest/srs_utest_service.hpp +++ b/trunk/src/utest/srs_utest_service.hpp @@ -34,6 +34,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. class MockSrsConnection : public ISrsConnection { +public: + // Whether switch the coroutine context when free the object, for special case test. + bool do_switch; public: MockSrsConnection(); virtual ~MockSrsConnection();