From d74f01e2d18191cb8b0e9bbe024e24a4355c6366 Mon Sep 17 00:00:00 2001 From: winlin Date: Fri, 2 May 2014 12:29:56 +0800 Subject: [PATCH] fix signal bug, break for gmc. fix SrsMessage leak, use common message to free payload. to 0.9.88 --- trunk/src/app/srs_app_server.cpp | 107 +++++++++++---------- trunk/src/app/srs_app_server.hpp | 1 + trunk/src/core/srs_core.hpp | 2 +- trunk/src/rtmp/srs_protocol_rtmp_stack.cpp | 15 ++- trunk/src/rtmp/srs_protocol_rtmp_stack.hpp | 19 +++- 5 files changed, 90 insertions(+), 54 deletions(-) diff --git a/trunk/src/app/srs_app_server.cpp b/trunk/src/app/srs_app_server.cpp index 6ea98f082..b586bf551 100644 --- a/trunk/src/app/srs_app_server.cpp +++ b/trunk/src/app/srs_app_server.cpp @@ -532,55 +532,8 @@ int SrsServer::ingest() int SrsServer::cycle() { int ret = ERROR_SUCCESS; - - // find the max loop - int max = srs_max(0, SRS_SYS_TIME_RESOLUTION_MS_TIMES); - max = srs_max(max, SRS_SYS_RUSAGE_RESOLUTION_TIMES); - max = srs_max(max, SRS_SYS_CPU_STAT_RESOLUTION_TIMES); - max = srs_max(max, SRS_SYS_MEMINFO_RESOLUTION_TIMES); - - // the deamon thread, update the time cache - while (true) { - for (int i = 1; i < max + 1; i++) { - st_usleep(SRS_SYS_CYCLE_INTERVAL * 1000); - -// for gperf heap checker, -// @see: research/gperftools/heap-checker/heap_checker.cc -// if user interrupt the program, exit to check mem leak. -// but, if gperf, use reload to ensure main return normally, -// because directly exit will cause core-dump. -#ifdef SRS_AUTO_GPERF_MC - if (signal_gmc_stop) { - break; - } -#endif - - if (signal_reload) { - signal_reload = false; - srs_info("get signal reload, to reload the config."); - - if ((ret = _srs_config->reload()) != ERROR_SUCCESS) { - srs_error("reload config failed. ret=%d", ret); - return ret; - } - srs_trace("reload config success."); - } - - // update the cache time or rusage. - if ((i % SRS_SYS_TIME_RESOLUTION_MS_TIMES) == 0) { - srs_update_system_time_ms(); - } - if ((i % SRS_SYS_RUSAGE_RESOLUTION_TIMES) == 0) { - srs_update_system_rusage(); - } - if ((i % SRS_SYS_CPU_STAT_RESOLUTION_TIMES) == 0) { - srs_update_proc_stat(); - } - if ((i % SRS_SYS_MEMINFO_RESOLUTION_TIMES) == 0) { - srs_update_meminfo(); - } - } - } + + ret = do_cycle(); #ifdef SRS_AUTO_INGEST ingester->stop(); @@ -629,6 +582,62 @@ void SrsServer::on_signal(int signo) } } +int SrsServer::do_cycle() +{ + int ret = ERROR_SUCCESS; + + // find the max loop + int max = srs_max(0, SRS_SYS_TIME_RESOLUTION_MS_TIMES); + max = srs_max(max, SRS_SYS_RUSAGE_RESOLUTION_TIMES); + max = srs_max(max, SRS_SYS_CPU_STAT_RESOLUTION_TIMES); + max = srs_max(max, SRS_SYS_MEMINFO_RESOLUTION_TIMES); + + // the deamon thread, update the time cache + while (true) { + for (int i = 1; i < max + 1; i++) { + st_usleep(SRS_SYS_CYCLE_INTERVAL * 1000); + +// for gperf heap checker, +// @see: research/gperftools/heap-checker/heap_checker.cc +// if user interrupt the program, exit to check mem leak. +// but, if gperf, use reload to ensure main return normally, +// because directly exit will cause core-dump. +#ifdef SRS_AUTO_GPERF_MC + if (signal_gmc_stop) { + return ret; + } +#endif + + if (signal_reload) { + signal_reload = false; + srs_info("get signal reload, to reload the config."); + + if ((ret = _srs_config->reload()) != ERROR_SUCCESS) { + srs_error("reload config failed. ret=%d", ret); + return ret; + } + srs_trace("reload config success."); + } + + // update the cache time or rusage. + if ((i % SRS_SYS_TIME_RESOLUTION_MS_TIMES) == 0) { + srs_update_system_time_ms(); + } + if ((i % SRS_SYS_RUSAGE_RESOLUTION_TIMES) == 0) { + srs_update_system_rusage(); + } + if ((i % SRS_SYS_CPU_STAT_RESOLUTION_TIMES) == 0) { + srs_update_proc_stat(); + } + if ((i % SRS_SYS_MEMINFO_RESOLUTION_TIMES) == 0) { + srs_update_meminfo(); + } + } + } + + return ret; +} + int SrsServer::listen_rtmp() { int ret = ERROR_SUCCESS; diff --git a/trunk/src/app/srs_app_server.hpp b/trunk/src/app/srs_app_server.hpp index 0ac856e18..7cdca2bd5 100644 --- a/trunk/src/app/srs_app_server.hpp +++ b/trunk/src/app/srs_app_server.hpp @@ -140,6 +140,7 @@ public: virtual void remove(SrsConnection* conn); virtual void on_signal(int signo); private: + virtual int do_cycle(); virtual int listen_rtmp(); virtual int listen_http_api(); virtual int listen_http_stream(); diff --git a/trunk/src/core/srs_core.hpp b/trunk/src/core/srs_core.hpp index 426372db5..5c4aeda11 100644 --- a/trunk/src/core/srs_core.hpp +++ b/trunk/src/core/srs_core.hpp @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // current release version #define VERSION_MAJOR "0" #define VERSION_MINOR "9" -#define VERSION_REVISION "87" +#define VERSION_REVISION "88" #define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION // server info. #define RTMP_SIG_SRS_KEY "srs" diff --git a/trunk/src/rtmp/srs_protocol_rtmp_stack.cpp b/trunk/src/rtmp/srs_protocol_rtmp_stack.cpp index 0703e9395..4b9faa17c 100644 --- a/trunk/src/rtmp/srs_protocol_rtmp_stack.cpp +++ b/trunk/src/rtmp/srs_protocol_rtmp_stack.cpp @@ -759,7 +759,7 @@ int SrsProtocol::send_and_free_packet(SrsPacket* packet, int stream_id) } // to message - SrsMessage* msg = new SrsMessage(); + SrsMessage* msg = new SrsCommonMessage(); msg->payload = (int8_t*)payload; msg->size = (int32_t)size; @@ -975,7 +975,7 @@ int SrsProtocol::read_message_header(SrsChunkStream* chunk, char fmt, int bh_siz bool is_first_chunk_of_msg = false; if (!chunk->msg) { is_first_chunk_of_msg = true; - chunk->msg = new SrsMessage(); + chunk->msg = new SrsCommonMessage(); srs_verbose("create message for new chunk, fmt=%d, cid=%d", fmt, chunk->cid); } @@ -1532,7 +1532,16 @@ SrsMessage::SrsMessage() } SrsMessage::~SrsMessage() -{ +{ +} + +SrsCommonMessage::SrsCommonMessage() +{ +} + +SrsCommonMessage::~SrsCommonMessage() +{ + srs_freepa(payload); } SrsSharedPtrMessage::__SrsSharedPtr::__SrsSharedPtr() diff --git a/trunk/src/rtmp/srs_protocol_rtmp_stack.hpp b/trunk/src/rtmp/srs_protocol_rtmp_stack.hpp index 4f7e711b9..012de2113 100644 --- a/trunk/src/rtmp/srs_protocol_rtmp_stack.hpp +++ b/trunk/src/rtmp/srs_protocol_rtmp_stack.hpp @@ -325,6 +325,12 @@ public: * message is raw data RTMP message, bytes oriented, * protcol always recv RTMP message, and can send RTMP message or RTMP packet. * the shared-ptr message is a special RTMP message, use ref-count for performance issue. +* +* @remark, never directly new SrsMessage, the constructor is protected, +* for in the SrsMessage, we never know whether we should free the message, +* for SrsCommonMessage, we should free the payload, +* while for SrsSharedPtrMessage, we should use ref-count to free it. +* so, use these two concrete message, SrsCommonMessage or SrsSharedPtrMessage instread. */ class SrsMessage { @@ -341,11 +347,22 @@ public: */ int32_t size; int8_t* payload; -public: +protected: SrsMessage(); +public: virtual ~SrsMessage(); }; +/** +* the common message used free the payload in common way. +*/ +class SrsCommonMessage : public SrsMessage +{ +public: + SrsCommonMessage(); + virtual ~SrsCommonMessage(); +}; + /** * shared ptr message. * for audio/video/data message that need less memory copy.