From 19e1f610a35e1f4120a567d6d0386801f8ac2a24 Mon Sep 17 00:00:00 2001 From: winlin Date: Mon, 8 Jun 2015 17:28:39 +0800 Subject: [PATCH 1/7] merge from bravo, parse the http reponse in json of bravo system. --- trunk/src/app/srs_app_http_hooks.cpp | 30 +++++++++++++++++++++++++-- trunk/src/kernel/srs_kernel_error.hpp | 4 ++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/trunk/src/app/srs_app_http_hooks.cpp b/trunk/src/app/srs_app_http_hooks.cpp index 3b99fb400..f9065226f 100644 --- a/trunk/src/app/srs_app_http_hooks.cpp +++ b/trunk/src/app/srs_app_http_hooks.cpp @@ -433,10 +433,36 @@ int SrsHttpHooks::do_post(std::string url, std::string req, int& code, string& r return ERROR_HTTP_STATUS_INVLIAD; } - // TODO: FIXME: parse json. - if (res.empty() || res != SRS_HTTP_RESPONSE_OK) { + if (res.empty()) { return ERROR_HTTP_DATA_INVLIAD; } + + // parse string res to json. + SrsJsonAny* info = SrsJsonAny::loads((char*)res.c_str()); + SrsAutoFree(SrsJsonAny, info); + + // if res is number of error code + if (!info->is_object()) { + if (res != SRS_HTTP_RESPONSE_OK) { + return ERROR_HTTP_DATA_INVLIAD; + } + return ret; + } + + // if res is json obj, like: {"code": 0, "data": ""} + SrsJsonObject* res_info = info->to_object(); + SrsJsonAny* res_code = NULL; + if ((res_code = res_info->ensure_property_integer("code")) == NULL) { + ret = ERROR_RESPONSE_CODE; + srs_error("res code error, ret=%d", ret); + return ret; + } + + if ((res_code->to_integer()) != ERROR_SUCCESS) { + ret = ERROR_RESPONSE_CODE; + srs_error("res code error, ret=%d, code=%d", ret, code); + return ret; + } return ret; } diff --git a/trunk/src/kernel/srs_kernel_error.hpp b/trunk/src/kernel/srs_kernel_error.hpp index 5f43da1d0..ebcf23909 100644 --- a/trunk/src/kernel/srs_kernel_error.hpp +++ b/trunk/src/kernel/srs_kernel_error.hpp @@ -223,6 +223,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define ERROR_HDS_OPEN_FRAGMENT_FAILED 3060 #define ERROR_HDS_WRITE_FRAGMENT_FAILED 3061 #define ERROR_HLS_NO_STREAM 3062 +#define ERROR_JSON_LOADS 3063 +#define ERROR_RESPONSE_CODE 3064 /////////////////////////////////////////////////////// // HTTP/StreamCaster protocol error. @@ -262,6 +264,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // user-define error. /////////////////////////////////////////////////////// #define ERROR_USER_START 9000 +#define ERROR_USER_DISCONNECT 9001 +#define ERROR_SOURCE_NOT_FOUND 9002 #define ERROR_USER_END 9999 /** From 863dddde09ba9d85349ae683fc7b2dbe9b73c940 Mon Sep 17 00:00:00 2001 From: winlin Date: Mon, 8 Jun 2015 17:43:28 +0800 Subject: [PATCH 2/7] fix typo of code. --- trunk/src/app/srs_app_conn.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trunk/src/app/srs_app_conn.hpp b/trunk/src/app/srs_app_conn.hpp index e9426c395..d5130bf71 100644 --- a/trunk/src/app/srs_app_conn.hpp +++ b/trunk/src/app/srs_app_conn.hpp @@ -86,7 +86,7 @@ protected: /** * whether the connection is disposed, * when disposed, connection should stop cycle and cleanup itself. - */; + */ bool disposed; public: SrsConnection(IConnectionManager* cm, st_netfd_t c); From f347099fd16fa8ebe9e624a747df8d92b1f5d6f0 Mon Sep 17 00:00:00 2001 From: winlin Date: Tue, 9 Jun 2015 10:13:25 +0800 Subject: [PATCH 3/7] for memory leak detect, move the payload create to message. --- trunk/src/kernel/srs_kernel_flv.cpp | 12 ++++++++++++ trunk/src/kernel/srs_kernel_flv.hpp | 6 +++++- trunk/src/protocol/srs_rtmp_stack.cpp | 7 +------ 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/trunk/src/kernel/srs_kernel_flv.cpp b/trunk/src/kernel/srs_kernel_flv.cpp index 60bd3cfcc..a9ce2d82e 100644 --- a/trunk/src/kernel/srs_kernel_flv.cpp +++ b/trunk/src/kernel/srs_kernel_flv.cpp @@ -166,6 +166,18 @@ SrsCommonMessage::~SrsCommonMessage() srs_freep(payload); } +void SrsCommonMessage::create_payload(int size) +{ + srs_freep(payload); + + payload = new char[size]; + srs_verbose("create payload for RTMP message. size=%d", size); + +#ifdef SRS_MEM_WATCH + srs_memory_watch(payload, "RTMP.msg.payload", size); +#endif +} + SrsSharedPtrMessage::SrsSharedPtrPayload::SrsSharedPtrPayload() { payload = NULL; diff --git a/trunk/src/kernel/srs_kernel_flv.hpp b/trunk/src/kernel/srs_kernel_flv.hpp index a33e1a320..ed45a7bf0 100644 --- a/trunk/src/kernel/srs_kernel_flv.hpp +++ b/trunk/src/kernel/srs_kernel_flv.hpp @@ -283,8 +283,12 @@ public: char* payload; public: SrsCommonMessage(); -public: virtual ~SrsCommonMessage(); +public: + /** + * alloc the payload to specified size of bytes. + */ + virtual void create_payload(int size); }; /** diff --git a/trunk/src/protocol/srs_rtmp_stack.cpp b/trunk/src/protocol/srs_rtmp_stack.cpp index b4893955a..77a66249a 100644 --- a/trunk/src/protocol/srs_rtmp_stack.cpp +++ b/trunk/src/protocol/srs_rtmp_stack.cpp @@ -30,7 +30,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include #include -#include // for srs-librtmp, @see https://github.com/simple-rtmp-server/srs/issues/213 #ifndef _WIN32 @@ -1411,11 +1410,7 @@ int SrsProtocol::read_message_payload(SrsChunkStream* chunk, SrsCommonMessage** // create msg payload if not initialized if (!chunk->msg->payload) { - chunk->msg->payload = new char[chunk->header.payload_length]; - srs_verbose("create payload for RTMP message. size=%d", chunk->header.payload_length); -#ifdef SRS_MEM_WATCH - srs_memory_watch(chunk->msg->payload, "msg.payload", chunk->header.payload_length); -#endif + chunk->msg->create_payload(chunk->header.payload_length); } // read payload to buffer From 7996b3b7894a697bac77fb1d1979c4f4d2d6e749 Mon Sep 17 00:00:00 2001 From: winlin Date: Tue, 9 Jun 2015 10:52:32 +0800 Subject: [PATCH 4/7] add warning for gmp, use gmc to detect memory leak. --- trunk/auto/summary.sh | 4 ++-- trunk/src/main/srs_main_server.cpp | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/trunk/auto/summary.sh b/trunk/auto/summary.sh index cbe5cc075..4ed5b1376 100755 --- a/trunk/auto/summary.sh +++ b/trunk/auto/summary.sh @@ -37,11 +37,11 @@ echo -e "\${GREEN}build summary:\${BLACK}" echo -e " \${BLACK}+------------------------------------------------------------------------------------\${BLACK}" echo -e " |${SrsGperfSummaryColor}gperf @see: https://github.com/simple-rtmp-server/srs/wiki/v1_CN_GPERF\${BLACK}" echo -e " | ${SrsGperfMCSummaryColor}gmc @see: http://google-perftools.googlecode.com/svn/trunk/doc/heap_checker.html\${BLACK}" -echo -e " | ${SrsGperfMCSummaryColor}gmc: gperf memory check\${BLACK}" +echo -e " | ${SrsGperfMCSummaryColor}gmc: gperf memory check, or memory leak detect\${BLACK}" echo -e " | ${SrsGperfMCSummaryColor}env PPROF_PATH=./objs/pprof HEAPCHECK=normal ./objs/srs -c conf/console.conf # start gmc\${BLACK}" echo -e " | ${SrsGperfMCSummaryColor}killall -2 srs # or CTRL+C to stop gmc\${BLACK}" echo -e " | ${SrsGperfMPSummaryColor}gmp @see: http://google-perftools.googlecode.com/svn/trunk/doc/heapprofile.html\${BLACK}" -echo -e " | ${SrsGperfMPSummaryColor}gmp: gperf memory profile\${BLACK}" +echo -e " | ${SrsGperfMPSummaryColor}gmp: gperf memory profile, similar to gcp\${BLACK}" echo -e " | ${SrsGperfMPSummaryColor}rm -f gperf.srs.gmp*; ./objs/srs -c conf/console.conf # start gmp\${BLACK}" echo -e " | ${SrsGperfMPSummaryColor}killall -2 srs # or CTRL+C to stop gmp\${BLACK}" echo -e " | ${SrsGperfMPSummaryColor}./objs/pprof --text objs/srs gperf.srs.gmp* # to analysis memory profile\${BLACK}" diff --git a/trunk/src/main/srs_main_server.cpp b/trunk/src/main/srs_main_server.cpp index d0750f2fe..b53504b7e 100644 --- a/trunk/src/main/srs_main_server.cpp +++ b/trunk/src/main/srs_main_server.cpp @@ -254,6 +254,11 @@ int main(int argc, char** argv) "it is not possible to run both the heap-checker and heap profiler at the same time"); #endif + // never use gmp to check memory leak. +#ifdef SRS_AUTO_GPERF_MP + #warning "gmp is not used for memory leak, please use gmc instead." +#endif + // never use srs log(srs_trace, srs_error, etc) before config parse the option, // which will load the log config and apply it. if ((ret = _srs_config->parse_options(argc, argv)) != ERROR_SUCCESS) { From d317528af989314f37268914dfd00d8404a90a67 Mon Sep 17 00:00:00 2001 From: winlin Date: Tue, 9 Jun 2015 11:19:28 +0800 Subject: [PATCH 5/7] refine the signal manager. --- trunk/src/app/srs_app_server.cpp | 40 +++++++++++++++++--------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/trunk/src/app/srs_app_server.cpp b/trunk/src/app/srs_app_server.cpp index 575372d83..9b86c8c73 100644 --- a/trunk/src/app/srs_app_server.cpp +++ b/trunk/src/app/srs_app_server.cpp @@ -374,8 +374,6 @@ SrsSignalManager::SrsSignalManager(SrsServer* server) SrsSignalManager::~SrsSignalManager() { - srs_freep(pthread); - srs_close_stfd(signal_read_stfd); if (sig_pipe[0] > 0) { @@ -384,24 +382,13 @@ SrsSignalManager::~SrsSignalManager() if (sig_pipe[1] > 0) { ::close(sig_pipe[1]); } + + srs_freep(pthread); } int SrsSignalManager::initialize() { int ret = ERROR_SUCCESS; - return ret; -} - -int SrsSignalManager::start() -{ - int ret = ERROR_SUCCESS; - - /** - * Note that if multiple processes are used (see below), - * the signal pipe should be initialized after the fork(2) call - * so that each process has its own private pipe. - */ - struct sigaction sa; /* Create signal pipe */ if (pipe(sig_pipe) < 0) { @@ -410,6 +397,24 @@ int SrsSignalManager::start() return ret; } + if ((signal_read_stfd = st_netfd_open(sig_pipe[0])) == NULL) { + ret = ERROR_SYSTEM_CREATE_PIPE; + srs_error("create signal manage st pipe failed. ret=%d", ret); + return ret; + } + + return ret; +} + +int SrsSignalManager::start() +{ + /** + * Note that if multiple processes are used (see below), + * the signal pipe should be initialized after the fork(2) call + * so that each process has its own private pipe. + */ + struct sigaction sa; + /* Install sig_catcher() as a signal handler */ sa.sa_handler = SrsSignalManager::sig_catcher; sigemptyset(&sa.sa_mask); @@ -439,10 +444,6 @@ int SrsSignalManager::start() int SrsSignalManager::cycle() { int ret = ERROR_SUCCESS; - - if (signal_read_stfd == NULL) { - signal_read_stfd = st_netfd_open(sig_pipe[0]); - } int signo; @@ -852,6 +853,7 @@ int SrsServer::cycle() #else srs_warn("main cycle terminated, system quit normally."); dispose(); + srs_trace("srs terminated"); exit(0); #endif From 66837ffa6e67a68b03192702e1677d79a738f89c Mon Sep 17 00:00:00 2001 From: winlin Date: Tue, 9 Jun 2015 11:47:04 +0800 Subject: [PATCH 6/7] fix the thread stop bug, must wait when not joinable. --- trunk/src/app/srs_app_server.cpp | 2 -- trunk/src/app/srs_app_server.hpp | 6 +++++- trunk/src/app/srs_app_thread.cpp | 23 ++++++++++++----------- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/trunk/src/app/srs_app_server.cpp b/trunk/src/app/srs_app_server.cpp index 9b86c8c73..c3ac0a5fb 100644 --- a/trunk/src/app/srs_app_server.cpp +++ b/trunk/src/app/srs_app_server.cpp @@ -539,8 +539,6 @@ void SrsServer::destroy() } srs_freep(signal_manager); - - srs_freep(handler); } void SrsServer::dispose() diff --git a/trunk/src/app/srs_app_server.hpp b/trunk/src/app/srs_app_server.hpp index 32646afa1..ac1e51414 100644 --- a/trunk/src/app/srs_app_server.hpp +++ b/trunk/src/app/srs_app_server.hpp @@ -293,10 +293,14 @@ private: virtual void dispose(); // server startup workflow, @see run_master() public: + /** + * initialize server with callback handler. + * @remark user must free the cycle handler. + */ virtual int initialize(ISrsServerCycle* cycle_handler); + virtual int initialize_st(); virtual int initialize_signal(); virtual int acquire_pid_file(); - virtual int initialize_st(); virtual int listen(); virtual int register_signal(); virtual int http_handle(); diff --git a/trunk/src/app/srs_app_thread.cpp b/trunk/src/app/srs_app_thread.cpp index dbc09ee0d..0007df3ea 100644 --- a/trunk/src/app/srs_app_thread.cpp +++ b/trunk/src/app/srs_app_thread.cpp @@ -129,19 +129,20 @@ namespace internal { if (ret) { srs_warn("core: ignore join thread failed."); } + } + + // wait the thread actually terminated. + // sometimes the thread join return -1, for example, + // when thread use st_recvfrom, the thread join return -1. + // so here, we use a variable to ensure the thread stopped. + // @remark even the thread not joinable, we must ensure the thread stopped when stop. + while (!really_terminated) { + st_usleep(10 * 1000); - // wait the thread actually terminated. - // sometimes the thread join return -1, for example, - // when thread use st_recvfrom, the thread join return -1. - // so here, we use a variable to ensure the thread stopped. - while (!really_terminated) { - st_usleep(10 * 1000); - - if (really_terminated) { - break; - } - srs_warn("core: wait thread to actually terminated"); + if (really_terminated) { + break; } + srs_warn("core: wait thread to actually terminated"); } tid = NULL; From 969ed7b0aee320d3c6348e00721e7932bd9a7f59 Mon Sep 17 00:00:00 2001 From: winlin Date: Tue, 9 Jun 2015 11:51:40 +0800 Subject: [PATCH 7/7] refine build summary. --- trunk/auto/summary.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/trunk/auto/summary.sh b/trunk/auto/summary.sh index 4ed5b1376..b1c3c2683 100755 --- a/trunk/auto/summary.sh +++ b/trunk/auto/summary.sh @@ -38,8 +38,9 @@ echo -e " \${BLACK}+-------------------------------------------------------- echo -e " |${SrsGperfSummaryColor}gperf @see: https://github.com/simple-rtmp-server/srs/wiki/v1_CN_GPERF\${BLACK}" echo -e " | ${SrsGperfMCSummaryColor}gmc @see: http://google-perftools.googlecode.com/svn/trunk/doc/heap_checker.html\${BLACK}" echo -e " | ${SrsGperfMCSummaryColor}gmc: gperf memory check, or memory leak detect\${BLACK}" -echo -e " | ${SrsGperfMCSummaryColor}env PPROF_PATH=./objs/pprof HEAPCHECK=normal ./objs/srs -c conf/console.conf # start gmc\${BLACK}" +echo -e " | ${SrsGperfMCSummaryColor}env PPROF_PATH=./objs/pprof HEAPCHECK=normal ./objs/srs -c conf/console.conf 2>gmc.log # start gmc\${BLACK}" echo -e " | ${SrsGperfMCSummaryColor}killall -2 srs # or CTRL+C to stop gmc\${BLACK}" +echo -e " | ${SrsGperfMCSummaryColor}cat gmc.log # to analysis memory leak\${BLACK}" echo -e " | ${SrsGperfMPSummaryColor}gmp @see: http://google-perftools.googlecode.com/svn/trunk/doc/heapprofile.html\${BLACK}" echo -e " | ${SrsGperfMPSummaryColor}gmp: gperf memory profile, similar to gcp\${BLACK}" echo -e " | ${SrsGperfMPSummaryColor}rm -f gperf.srs.gmp*; ./objs/srs -c conf/console.conf # start gmp\${BLACK}"