From adf7ef451180da265253b948b018228456c7cb2a Mon Sep 17 00:00:00 2001 From: winlin Date: Tue, 28 Jan 2020 21:35:06 +0800 Subject: [PATCH] Fix #1230, racing condition in source fetch or create. 3.0.110 --- README.md | 2 ++ trunk/src/app/srs_app_source.cpp | 12 ++++++++++++ trunk/src/app/srs_app_source.hpp | 2 ++ trunk/src/core/srs_core.hpp | 2 +- trunk/src/service/srs_service_st.cpp | 3 +++ trunk/src/service/srs_service_st.hpp | 7 ++++--- 6 files changed, 24 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 1e27dcf5b..e792e3df1 100755 --- a/README.md +++ b/README.md @@ -146,6 +146,7 @@ For previous versions, please read: ## V3 changes +* v3.0, 2020-01-28, Fix [#1230][bug #1230], racing condition in source fetch or create. 3.0.110 * v3.0, 2020-01-27, Fix [#1303][bug #1303], do not dispatch previous meta when not publishing. 3.0.109 * v3.0, 2020-01-26, Allow use libst.so for ST is MPL license. * v3.0, 2020-01-26, Fix [#607][bug #607], set RTMP identifying recursive depth to 3. @@ -1630,6 +1631,7 @@ Winlin [bug #878]: https://github.com/ossrs/srs/issues/878 [bug #607]: https://github.com/ossrs/srs/issues/607 [bug #1303]: https://github.com/ossrs/srs/issues/1303 +[bug #1230]: https://github.com/ossrs/srs/issues/1230 [bug #xxxxxxxxxxxxx]: https://github.com/ossrs/srs/issues/xxxxxxxxxxxxx [exo #828]: https://github.com/google/ExoPlayer/pull/828 diff --git a/trunk/src/app/srs_app_source.cpp b/trunk/src/app/srs_app_source.cpp index 3bf9e0c65..94579de4b 100755 --- a/trunk/src/app/srs_app_source.cpp +++ b/trunk/src/app/srs_app_source.cpp @@ -1650,15 +1650,26 @@ SrsSourceManager* _srs_sources = new SrsSourceManager(); SrsSourceManager::SrsSourceManager() { + lock = NULL; } SrsSourceManager::~SrsSourceManager() { + srs_mutex_destroy(lock); } srs_error_t SrsSourceManager::fetch_or_create(SrsRequest* r, ISrsSourceHandler* h, SrsSource** pps) { srs_error_t err = srs_success; + + // Lazy create lock, because ST is not ready in SrsSourceManager constructor. + if (!lock) { + lock = srs_mutex_new(); + } + + // Use lock to protect coroutine switch. + // @bug https://github.com/ossrs/srs/issues/1230 + SrsLocker(lock); SrsSource* source = NULL; if ((source = fetch(r)) != NULL) { @@ -1676,6 +1687,7 @@ srs_error_t SrsSourceManager::fetch_or_create(SrsRequest* r, ISrsSourceHandler* if ((err = source->initialize(r, h)) != srs_success) { return srs_error_wrap(err, "init source %s", r->get_stream_url().c_str()); } + srs_usleep(10 * SRS_UTIME_SECONDS); pool[stream_url] = source; diff --git a/trunk/src/app/srs_app_source.hpp b/trunk/src/app/srs_app_source.hpp index dba9540da..8cb79f478 100644 --- a/trunk/src/app/srs_app_source.hpp +++ b/trunk/src/app/srs_app_source.hpp @@ -33,6 +33,7 @@ #include #include #include +#include class SrsFormat; class SrsRtmpFormat; @@ -443,6 +444,7 @@ public: class SrsSourceManager { private: + srs_mutex_t lock; std::map pool; public: SrsSourceManager(); diff --git a/trunk/src/core/srs_core.hpp b/trunk/src/core/srs_core.hpp index 6fb3a06b6..e3d8c838e 100644 --- a/trunk/src/core/srs_core.hpp +++ b/trunk/src/core/srs_core.hpp @@ -27,7 +27,7 @@ // The version config. #define VERSION_MAJOR 3 #define VERSION_MINOR 0 -#define VERSION_REVISION 109 +#define VERSION_REVISION 110 // The macros generated by configure script. #include diff --git a/trunk/src/service/srs_service_st.cpp b/trunk/src/service/srs_service_st.cpp index d8d9c3892..f63cd4279 100644 --- a/trunk/src/service/srs_service_st.cpp +++ b/trunk/src/service/srs_service_st.cpp @@ -356,6 +356,9 @@ srs_mutex_t srs_mutex_new() int srs_mutex_destroy(srs_mutex_t mutex) { + if (!mutex) { + return 0; + } return st_mutex_destroy((st_mutex_t)mutex); } diff --git a/trunk/src/service/srs_service_st.hpp b/trunk/src/service/srs_service_st.hpp index ebeb833ad..510b9ba8a 100644 --- a/trunk/src/service/srs_service_st.hpp +++ b/trunk/src/service/srs_service_st.hpp @@ -104,12 +104,13 @@ class impl__SrsLocker private: srs_mutex_t* lock; public: - impl__SrsLocker(srs_mutex_t* l) : lock(l) { - int r0 = srs_mutex_lock(lock); + impl__SrsLocker(srs_mutex_t* l) { + lock = l; + int r0 = srs_mutex_lock(*lock); srs_assert(!r0); } virtual ~impl__SrsLocker() { - int r0 = srs_mutex_unlock(lock); + int r0 = srs_mutex_unlock(*lock); srs_assert(!r0); } };