diff --git a/trunk/auto/summary.sh b/trunk/auto/summary.sh index cbe5cc075..b1c3c2683 100755 --- a/trunk/auto/summary.sh +++ b/trunk/auto/summary.sh @@ -37,11 +37,12 @@ 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}env PPROF_PATH=./objs/pprof HEAPCHECK=normal ./objs/srs -c conf/console.conf # start gmc\${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 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\${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/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); 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/app/srs_app_server.cpp b/trunk/src/app/srs_app_server.cpp index 575372d83..c3ac0a5fb 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,18 +382,32 @@ SrsSignalManager::~SrsSignalManager() if (sig_pipe[1] > 0) { ::close(sig_pipe[1]); } + + srs_freep(pthread); } int SrsSignalManager::initialize() { int ret = ERROR_SUCCESS; + + /* Create signal pipe */ + if (pipe(sig_pipe) < 0) { + ret = ERROR_SYSTEM_CREATE_PIPE; + srs_error("create signal manager pipe failed. ret=%d", ret); + 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() { - int ret = ERROR_SUCCESS; - /** * Note that if multiple processes are used (see below), * the signal pipe should be initialized after the fork(2) call @@ -403,13 +415,6 @@ int SrsSignalManager::start() */ struct sigaction sa; - /* Create signal pipe */ - if (pipe(sig_pipe) < 0) { - ret = ERROR_SYSTEM_CREATE_PIPE; - srs_error("create signal manager pipe failed. ret=%d", ret); - return ret; - } - /* 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; @@ -538,8 +539,6 @@ void SrsServer::destroy() } srs_freep(signal_manager); - - srs_freep(handler); } void SrsServer::dispose() @@ -852,6 +851,7 @@ int SrsServer::cycle() #else srs_warn("main cycle terminated, system quit normally."); dispose(); + srs_trace("srs terminated"); exit(0); #endif 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; 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 /** 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/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) { 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