winlin

Merge branch '2.0release' into develop

@@ -37,11 +37,12 @@ echo -e "\${GREEN}build summary:\${BLACK}" @@ -37,11 +37,12 @@ echo -e "\${GREEN}build summary:\${BLACK}"
37 echo -e " \${BLACK}+------------------------------------------------------------------------------------\${BLACK}" 37 echo -e " \${BLACK}+------------------------------------------------------------------------------------\${BLACK}"
38 echo -e " |${SrsGperfSummaryColor}gperf @see: https://github.com/simple-rtmp-server/srs/wiki/v1_CN_GPERF\${BLACK}" 38 echo -e " |${SrsGperfSummaryColor}gperf @see: https://github.com/simple-rtmp-server/srs/wiki/v1_CN_GPERF\${BLACK}"
39 echo -e " | ${SrsGperfMCSummaryColor}gmc @see: http://google-perftools.googlecode.com/svn/trunk/doc/heap_checker.html\${BLACK}" 39 echo -e " | ${SrsGperfMCSummaryColor}gmc @see: http://google-perftools.googlecode.com/svn/trunk/doc/heap_checker.html\${BLACK}"
40 -echo -e " | ${SrsGperfMCSummaryColor}gmc: gperf memory check\${BLACK}"  
41 -echo -e " | ${SrsGperfMCSummaryColor}env PPROF_PATH=./objs/pprof HEAPCHECK=normal ./objs/srs -c conf/console.conf # start gmc\${BLACK}" 40 +echo -e " | ${SrsGperfMCSummaryColor}gmc: gperf memory check, or memory leak detect\${BLACK}"
  41 +echo -e " | ${SrsGperfMCSummaryColor}env PPROF_PATH=./objs/pprof HEAPCHECK=normal ./objs/srs -c conf/console.conf 2>gmc.log # start gmc\${BLACK}"
42 echo -e " | ${SrsGperfMCSummaryColor}killall -2 srs # or CTRL+C to stop gmc\${BLACK}" 42 echo -e " | ${SrsGperfMCSummaryColor}killall -2 srs # or CTRL+C to stop gmc\${BLACK}"
  43 +echo -e " | ${SrsGperfMCSummaryColor}cat gmc.log # to analysis memory leak\${BLACK}"
43 echo -e " | ${SrsGperfMPSummaryColor}gmp @see: http://google-perftools.googlecode.com/svn/trunk/doc/heapprofile.html\${BLACK}" 44 echo -e " | ${SrsGperfMPSummaryColor}gmp @see: http://google-perftools.googlecode.com/svn/trunk/doc/heapprofile.html\${BLACK}"
44 -echo -e " | ${SrsGperfMPSummaryColor}gmp: gperf memory profile\${BLACK}" 45 +echo -e " | ${SrsGperfMPSummaryColor}gmp: gperf memory profile, similar to gcp\${BLACK}"
45 echo -e " | ${SrsGperfMPSummaryColor}rm -f gperf.srs.gmp*; ./objs/srs -c conf/console.conf # start gmp\${BLACK}" 46 echo -e " | ${SrsGperfMPSummaryColor}rm -f gperf.srs.gmp*; ./objs/srs -c conf/console.conf # start gmp\${BLACK}"
46 echo -e " | ${SrsGperfMPSummaryColor}killall -2 srs # or CTRL+C to stop gmp\${BLACK}" 47 echo -e " | ${SrsGperfMPSummaryColor}killall -2 srs # or CTRL+C to stop gmp\${BLACK}"
47 echo -e " | ${SrsGperfMPSummaryColor}./objs/pprof --text objs/srs gperf.srs.gmp* # to analysis memory profile\${BLACK}" 48 echo -e " | ${SrsGperfMPSummaryColor}./objs/pprof --text objs/srs gperf.srs.gmp* # to analysis memory profile\${BLACK}"
@@ -86,7 +86,7 @@ protected: @@ -86,7 +86,7 @@ protected:
86 /** 86 /**
87 * whether the connection is disposed, 87 * whether the connection is disposed,
88 * when disposed, connection should stop cycle and cleanup itself. 88 * when disposed, connection should stop cycle and cleanup itself.
89 - */; 89 + */
90 bool disposed; 90 bool disposed;
91 public: 91 public:
92 SrsConnection(IConnectionManager* cm, st_netfd_t c); 92 SrsConnection(IConnectionManager* cm, st_netfd_t c);
@@ -433,11 +433,37 @@ int SrsHttpHooks::do_post(std::string url, std::string req, int& code, string& r @@ -433,11 +433,37 @@ int SrsHttpHooks::do_post(std::string url, std::string req, int& code, string& r
433 return ERROR_HTTP_STATUS_INVLIAD; 433 return ERROR_HTTP_STATUS_INVLIAD;
434 } 434 }
435 435
436 - // TODO: FIXME: parse json.  
437 - if (res.empty() || res != SRS_HTTP_RESPONSE_OK) { 436 + if (res.empty()) {
438 return ERROR_HTTP_DATA_INVLIAD; 437 return ERROR_HTTP_DATA_INVLIAD;
439 } 438 }
440 439
  440 + // parse string res to json.
  441 + SrsJsonAny* info = SrsJsonAny::loads((char*)res.c_str());
  442 + SrsAutoFree(SrsJsonAny, info);
  443 +
  444 + // if res is number of error code
  445 + if (!info->is_object()) {
  446 + if (res != SRS_HTTP_RESPONSE_OK) {
  447 + return ERROR_HTTP_DATA_INVLIAD;
  448 + }
  449 + return ret;
  450 + }
  451 +
  452 + // if res is json obj, like: {"code": 0, "data": ""}
  453 + SrsJsonObject* res_info = info->to_object();
  454 + SrsJsonAny* res_code = NULL;
  455 + if ((res_code = res_info->ensure_property_integer("code")) == NULL) {
  456 + ret = ERROR_RESPONSE_CODE;
  457 + srs_error("res code error, ret=%d", ret);
  458 + return ret;
  459 + }
  460 +
  461 + if ((res_code->to_integer()) != ERROR_SUCCESS) {
  462 + ret = ERROR_RESPONSE_CODE;
  463 + srs_error("res code error, ret=%d, code=%d", ret, code);
  464 + return ret;
  465 + }
  466 +
441 return ret; 467 return ret;
442 } 468 }
443 469
@@ -374,8 +374,6 @@ SrsSignalManager::SrsSignalManager(SrsServer* server) @@ -374,8 +374,6 @@ SrsSignalManager::SrsSignalManager(SrsServer* server)
374 374
375 SrsSignalManager::~SrsSignalManager() 375 SrsSignalManager::~SrsSignalManager()
376 { 376 {
377 - srs_freep(pthread);  
378 -  
379 srs_close_stfd(signal_read_stfd); 377 srs_close_stfd(signal_read_stfd);
380 378
381 if (sig_pipe[0] > 0) { 379 if (sig_pipe[0] > 0) {
@@ -384,18 +382,32 @@ SrsSignalManager::~SrsSignalManager() @@ -384,18 +382,32 @@ SrsSignalManager::~SrsSignalManager()
384 if (sig_pipe[1] > 0) { 382 if (sig_pipe[1] > 0) {
385 ::close(sig_pipe[1]); 383 ::close(sig_pipe[1]);
386 } 384 }
  385 +
  386 + srs_freep(pthread);
387 } 387 }
388 388
389 int SrsSignalManager::initialize() 389 int SrsSignalManager::initialize()
390 { 390 {
391 int ret = ERROR_SUCCESS; 391 int ret = ERROR_SUCCESS;
  392 +
  393 + /* Create signal pipe */
  394 + if (pipe(sig_pipe) < 0) {
  395 + ret = ERROR_SYSTEM_CREATE_PIPE;
  396 + srs_error("create signal manager pipe failed. ret=%d", ret);
  397 + return ret;
  398 + }
  399 +
  400 + if ((signal_read_stfd = st_netfd_open(sig_pipe[0])) == NULL) {
  401 + ret = ERROR_SYSTEM_CREATE_PIPE;
  402 + srs_error("create signal manage st pipe failed. ret=%d", ret);
  403 + return ret;
  404 + }
  405 +
392 return ret; 406 return ret;
393 } 407 }
394 408
395 int SrsSignalManager::start() 409 int SrsSignalManager::start()
396 { 410 {
397 - int ret = ERROR_SUCCESS;  
398 -  
399 /** 411 /**
400 * Note that if multiple processes are used (see below), 412 * Note that if multiple processes are used (see below),
401 * the signal pipe should be initialized after the fork(2) call 413 * the signal pipe should be initialized after the fork(2) call
@@ -403,13 +415,6 @@ int SrsSignalManager::start() @@ -403,13 +415,6 @@ int SrsSignalManager::start()
403 */ 415 */
404 struct sigaction sa; 416 struct sigaction sa;
405 417
406 - /* Create signal pipe */  
407 - if (pipe(sig_pipe) < 0) {  
408 - ret = ERROR_SYSTEM_CREATE_PIPE;  
409 - srs_error("create signal manager pipe failed. ret=%d", ret);  
410 - return ret;  
411 - }  
412 -  
413 /* Install sig_catcher() as a signal handler */ 418 /* Install sig_catcher() as a signal handler */
414 sa.sa_handler = SrsSignalManager::sig_catcher; 419 sa.sa_handler = SrsSignalManager::sig_catcher;
415 sigemptyset(&sa.sa_mask); 420 sigemptyset(&sa.sa_mask);
@@ -440,10 +445,6 @@ int SrsSignalManager::cycle() @@ -440,10 +445,6 @@ int SrsSignalManager::cycle()
440 { 445 {
441 int ret = ERROR_SUCCESS; 446 int ret = ERROR_SUCCESS;
442 447
443 - if (signal_read_stfd == NULL) {  
444 - signal_read_stfd = st_netfd_open(sig_pipe[0]);  
445 - }  
446 -  
447 int signo; 448 int signo;
448 449
449 /* Read the next signal from the pipe */ 450 /* Read the next signal from the pipe */
@@ -538,8 +539,6 @@ void SrsServer::destroy() @@ -538,8 +539,6 @@ void SrsServer::destroy()
538 } 539 }
539 540
540 srs_freep(signal_manager); 541 srs_freep(signal_manager);
541 -  
542 - srs_freep(handler);  
543 } 542 }
544 543
545 void SrsServer::dispose() 544 void SrsServer::dispose()
@@ -852,6 +851,7 @@ int SrsServer::cycle() @@ -852,6 +851,7 @@ int SrsServer::cycle()
852 #else 851 #else
853 srs_warn("main cycle terminated, system quit normally."); 852 srs_warn("main cycle terminated, system quit normally.");
854 dispose(); 853 dispose();
  854 + srs_trace("srs terminated");
855 exit(0); 855 exit(0);
856 #endif 856 #endif
857 857
@@ -293,10 +293,14 @@ private: @@ -293,10 +293,14 @@ private:
293 virtual void dispose(); 293 virtual void dispose();
294 // server startup workflow, @see run_master() 294 // server startup workflow, @see run_master()
295 public: 295 public:
  296 + /**
  297 + * initialize server with callback handler.
  298 + * @remark user must free the cycle handler.
  299 + */
296 virtual int initialize(ISrsServerCycle* cycle_handler); 300 virtual int initialize(ISrsServerCycle* cycle_handler);
  301 + virtual int initialize_st();
297 virtual int initialize_signal(); 302 virtual int initialize_signal();
298 virtual int acquire_pid_file(); 303 virtual int acquire_pid_file();
299 - virtual int initialize_st();  
300 virtual int listen(); 304 virtual int listen();
301 virtual int register_signal(); 305 virtual int register_signal();
302 virtual int http_handle(); 306 virtual int http_handle();
@@ -129,11 +129,13 @@ namespace internal { @@ -129,11 +129,13 @@ namespace internal {
129 if (ret) { 129 if (ret) {
130 srs_warn("core: ignore join thread failed."); 130 srs_warn("core: ignore join thread failed.");
131 } 131 }
  132 + }
132 133
133 // wait the thread actually terminated. 134 // wait the thread actually terminated.
134 // sometimes the thread join return -1, for example, 135 // sometimes the thread join return -1, for example,
135 // when thread use st_recvfrom, the thread join return -1. 136 // when thread use st_recvfrom, the thread join return -1.
136 // so here, we use a variable to ensure the thread stopped. 137 // so here, we use a variable to ensure the thread stopped.
  138 + // @remark even the thread not joinable, we must ensure the thread stopped when stop.
137 while (!really_terminated) { 139 while (!really_terminated) {
138 st_usleep(10 * 1000); 140 st_usleep(10 * 1000);
139 141
@@ -142,7 +144,6 @@ namespace internal { @@ -142,7 +144,6 @@ namespace internal {
142 } 144 }
143 srs_warn("core: wait thread to actually terminated"); 145 srs_warn("core: wait thread to actually terminated");
144 } 146 }
145 - }  
146 147
147 tid = NULL; 148 tid = NULL;
148 } 149 }
@@ -223,6 +223,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -223,6 +223,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
223 #define ERROR_HDS_OPEN_FRAGMENT_FAILED 3060 223 #define ERROR_HDS_OPEN_FRAGMENT_FAILED 3060
224 #define ERROR_HDS_WRITE_FRAGMENT_FAILED 3061 224 #define ERROR_HDS_WRITE_FRAGMENT_FAILED 3061
225 #define ERROR_HLS_NO_STREAM 3062 225 #define ERROR_HLS_NO_STREAM 3062
  226 +#define ERROR_JSON_LOADS 3063
  227 +#define ERROR_RESPONSE_CODE 3064
226 228
227 /////////////////////////////////////////////////////// 229 ///////////////////////////////////////////////////////
228 // HTTP/StreamCaster protocol error. 230 // HTTP/StreamCaster protocol error.
@@ -262,6 +264,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -262,6 +264,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
262 // user-define error. 264 // user-define error.
263 /////////////////////////////////////////////////////// 265 ///////////////////////////////////////////////////////
264 #define ERROR_USER_START 9000 266 #define ERROR_USER_START 9000
  267 +#define ERROR_USER_DISCONNECT 9001
  268 +#define ERROR_SOURCE_NOT_FOUND 9002
265 #define ERROR_USER_END 9999 269 #define ERROR_USER_END 9999
266 270
267 /** 271 /**
@@ -166,6 +166,18 @@ SrsCommonMessage::~SrsCommonMessage() @@ -166,6 +166,18 @@ SrsCommonMessage::~SrsCommonMessage()
166 srs_freep(payload); 166 srs_freep(payload);
167 } 167 }
168 168
  169 +void SrsCommonMessage::create_payload(int size)
  170 +{
  171 + srs_freep(payload);
  172 +
  173 + payload = new char[size];
  174 + srs_verbose("create payload for RTMP message. size=%d", size);
  175 +
  176 +#ifdef SRS_MEM_WATCH
  177 + srs_memory_watch(payload, "RTMP.msg.payload", size);
  178 +#endif
  179 +}
  180 +
169 SrsSharedPtrMessage::SrsSharedPtrPayload::SrsSharedPtrPayload() 181 SrsSharedPtrMessage::SrsSharedPtrPayload::SrsSharedPtrPayload()
170 { 182 {
171 payload = NULL; 183 payload = NULL;
@@ -283,8 +283,12 @@ public: @@ -283,8 +283,12 @@ public:
283 char* payload; 283 char* payload;
284 public: 284 public:
285 SrsCommonMessage(); 285 SrsCommonMessage();
286 -public:  
287 virtual ~SrsCommonMessage(); 286 virtual ~SrsCommonMessage();
  287 +public:
  288 + /**
  289 + * alloc the payload to specified size of bytes.
  290 + */
  291 + virtual void create_payload(int size);
288 }; 292 };
289 293
290 /** 294 /**
@@ -254,6 +254,11 @@ int main(int argc, char** argv) @@ -254,6 +254,11 @@ int main(int argc, char** argv)
254 "it is not possible to run both the heap-checker and heap profiler at the same time"); 254 "it is not possible to run both the heap-checker and heap profiler at the same time");
255 #endif 255 #endif
256 256
  257 + // never use gmp to check memory leak.
  258 +#ifdef SRS_AUTO_GPERF_MP
  259 + #warning "gmp is not used for memory leak, please use gmc instead."
  260 +#endif
  261 +
257 // never use srs log(srs_trace, srs_error, etc) before config parse the option, 262 // never use srs log(srs_trace, srs_error, etc) before config parse the option,
258 // which will load the log config and apply it. 263 // which will load the log config and apply it.
259 if ((ret = _srs_config->parse_options(argc, argv)) != ERROR_SUCCESS) { 264 if ((ret = _srs_config->parse_options(argc, argv)) != ERROR_SUCCESS) {
@@ -30,7 +30,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -30,7 +30,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 #include <srs_kernel_utility.hpp> 30 #include <srs_kernel_utility.hpp>
31 #include <srs_protocol_buffer.hpp> 31 #include <srs_protocol_buffer.hpp>
32 #include <srs_rtmp_utility.hpp> 32 #include <srs_rtmp_utility.hpp>
33 -#include <srs_core_mem_watch.hpp>  
34 33
35 // for srs-librtmp, @see https://github.com/simple-rtmp-server/srs/issues/213 34 // for srs-librtmp, @see https://github.com/simple-rtmp-server/srs/issues/213
36 #ifndef _WIN32 35 #ifndef _WIN32
@@ -1411,11 +1410,7 @@ int SrsProtocol::read_message_payload(SrsChunkStream* chunk, SrsCommonMessage** @@ -1411,11 +1410,7 @@ int SrsProtocol::read_message_payload(SrsChunkStream* chunk, SrsCommonMessage**
1411 1410
1412 // create msg payload if not initialized 1411 // create msg payload if not initialized
1413 if (!chunk->msg->payload) { 1412 if (!chunk->msg->payload) {
1414 - chunk->msg->payload = new char[chunk->header.payload_length];  
1415 - srs_verbose("create payload for RTMP message. size=%d", chunk->header.payload_length);  
1416 -#ifdef SRS_MEM_WATCH  
1417 - srs_memory_watch(chunk->msg->payload, "msg.payload", chunk->header.payload_length);  
1418 -#endif 1413 + chunk->msg->create_payload(chunk->header.payload_length);
1419 } 1414 }
1420 1415
1421 // read payload to buffer 1416 // read payload to buffer