diff --git a/README.md b/README.md index 9bbbfc2cd..5de795541 100755 --- a/README.md +++ b/README.md @@ -176,6 +176,7 @@ The ports used by SRS: ## V4 changes +* v4.0, 2021-05-08, Refine global or thread-local variables initialize. 4.0.104 * v4.0, 2021-05-07, RTC: Support circuit breaker. 4.0.103 * v4.0, 2021-05-07, RTC: Refine play stream find track. 4.0.102 * v4.0, 2021-05-07, RTC: Refine FastTimer to fixed interval. 4.0.101 diff --git a/trunk/src/app/srs_app_hybrid.cpp b/trunk/src/app/srs_app_hybrid.cpp index e398b0222..9e0079a75 100644 --- a/trunk/src/app/srs_app_hybrid.cpp +++ b/trunk/src/app/srs_app_hybrid.cpp @@ -208,10 +208,11 @@ SrsServer* SrsServerAdapter::instance() SrsHybridServer::SrsHybridServer() { - // Note that the timer depends on other global variables, - // so we MUST never create it in constructor. - timer20ms_ = NULL; - timer5s_ = NULL; + // Create global shared timer. + timer20ms_ = new SrsFastTimer("hybrid", 20 * SRS_UTIME_MILLISECONDS); + timer100ms_ = new SrsFastTimer("hybrid", 100 * SRS_UTIME_MILLISECONDS); + timer1s_ = new SrsFastTimer("hybrid", 1 * SRS_UTIME_SECONDS); + timer5s_ = new SrsFastTimer("hybrid", 5 * SRS_UTIME_SECONDS); clock_monitor_ = new SrsClockWallMonitor(); } @@ -219,7 +220,10 @@ SrsHybridServer::SrsHybridServer() SrsHybridServer::~SrsHybridServer() { srs_freep(clock_monitor_); + srs_freep(timer20ms_); + srs_freep(timer100ms_); + srs_freep(timer1s_); srs_freep(timer5s_); vector::iterator it; @@ -239,17 +243,6 @@ srs_error_t SrsHybridServer::initialize() { srs_error_t err = srs_success; - // init st - if ((err = srs_st_init()) != srs_success) { - return srs_error_wrap(err, "initialize st failed"); - } - - // Create global shared timer. - timer20ms_ = new SrsFastTimer("hybrid", 20 * SRS_UTIME_MILLISECONDS); - timer100ms_ = new SrsFastTimer("hybrid", 100 * SRS_UTIME_MILLISECONDS); - timer1s_ = new SrsFastTimer("hybrid", 1 * SRS_UTIME_SECONDS); - timer5s_ = new SrsFastTimer("hybrid", 5 * SRS_UTIME_SECONDS); - // Start the timer first. if ((err = timer20ms_->start()) != srs_success) { return srs_error_wrap(err, "start timer"); @@ -478,5 +471,5 @@ srs_error_t SrsHybridServer::on_timer(srs_utime_t interval) return err; } -SrsHybridServer* _srs_hybrid = new SrsHybridServer(); +SrsHybridServer* _srs_hybrid = NULL; diff --git a/trunk/src/app/srs_app_threads.cpp b/trunk/src/app/srs_app_threads.cpp index 77ee3d1b7..c81a07b52 100644 --- a/trunk/src/app/srs_app_threads.cpp +++ b/trunk/src/app/srs_app_threads.cpp @@ -83,12 +83,12 @@ srs_error_t SrsCircuitBreaker::initialize() bool SrsCircuitBreaker::hybrid_high_water_level() { - return enabled_ && hybrid_critical_water_level() || hybrid_high_water_level_; + return enabled_ && (hybrid_critical_water_level() || hybrid_high_water_level_); } bool SrsCircuitBreaker::hybrid_critical_water_level() { - return enabled_ && hybrid_dying_water_level() || hybrid_critical_water_level_; + return enabled_ && (hybrid_dying_water_level() || hybrid_critical_water_level_); } bool SrsCircuitBreaker::hybrid_dying_water_level() @@ -133,7 +133,7 @@ srs_error_t SrsCircuitBreaker::on_timer(srs_utime_t interval) // The hybrid thread cpu and memory. float thread_percent = stat->percent * 100; - if (enabled_ && hybrid_high_water_level() || hybrid_critical_water_level() || _srs_pps_snack2->r10s()) { + if (enabled_ && (hybrid_high_water_level() || hybrid_critical_water_level() || _srs_pps_snack2->r10s())) { srs_trace("CircuitBreaker: cpu=%.2f%%,%dMB, break=%d,%d,%d, cond=%.2f%%, snk=%d,%d,%d", u->percent * 100, memory, hybrid_high_water_level(), hybrid_critical_water_level(), hybrid_dying_water_level(), // Whether Circuit-Break is enable. @@ -147,3 +147,17 @@ srs_error_t SrsCircuitBreaker::on_timer(srs_utime_t interval) SrsCircuitBreaker* _srs_circuit_breaker = new SrsCircuitBreaker(); +srs_error_t srs_thread_initialize() +{ + srs_error_t err = srs_success; + + // init st + if ((err = srs_st_init()) != srs_success) { + return srs_error_wrap(err, "initialize st failed"); + } + + _srs_hybrid = new SrsHybridServer(); + + return err; +} + diff --git a/trunk/src/app/srs_app_threads.hpp b/trunk/src/app/srs_app_threads.hpp index 7e293b6fb..57fe7cbfb 100644 --- a/trunk/src/app/srs_app_threads.hpp +++ b/trunk/src/app/srs_app_threads.hpp @@ -63,5 +63,8 @@ private: extern SrsCircuitBreaker* _srs_circuit_breaker; +// Initialize global or thread-local variables. +extern srs_error_t srs_thread_initialize(); + #endif diff --git a/trunk/src/core/srs_core_version4.hpp b/trunk/src/core/srs_core_version4.hpp index 7d3af0f74..56062eeec 100644 --- a/trunk/src/core/srs_core_version4.hpp +++ b/trunk/src/core/srs_core_version4.hpp @@ -26,6 +26,6 @@ #define VERSION_MAJOR 4 #define VERSION_MINOR 0 -#define VERSION_REVISION 103 +#define VERSION_REVISION 104 #endif diff --git a/trunk/src/main/srs_main_server.cpp b/trunk/src/main/srs_main_server.cpp index fd0fe5804..727c41b45 100644 --- a/trunk/src/main/srs_main_server.cpp +++ b/trunk/src/main/srs_main_server.cpp @@ -87,6 +87,11 @@ SrsServer* _srs_server = NULL; srs_error_t do_main(int argc, char** argv) { srs_error_t err = srs_success; + + // Initialize global or thread-local variables. + if ((err = srs_thread_initialize()) != srs_success) { + return srs_error_wrap(err, "thread init"); + } // TODO: support both little and big endian. srs_assert(srs_is_little_endian());