winlin

fix #244, conn thread use cond to wait for recv thread error. 2.0.47.

@@ -485,6 +485,7 @@ Supported operating systems and hardware: @@ -485,6 +485,7 @@ Supported operating systems and hardware:
485 * 2013-10-17, Created.<br/> 485 * 2013-10-17, Created.<br/>
486 486
487 ## History 487 ## History
  488 +* v2.0, 2014-12-03, fix [#244](https://github.com/winlinvip/simple-rtmp-server/issues/244), conn thread use cond to wait for recv thread error. 2.0.47.
488 * v2.0, 2014-12-02, merge [#239](https://github.com/winlinvip/simple-rtmp-server/pull/239), traverse the token before response connect. 2.0.45. 489 * v2.0, 2014-12-02, merge [#239](https://github.com/winlinvip/simple-rtmp-server/pull/239), traverse the token before response connect. 2.0.45.
489 * v2.0, 2014-12-02, srs-librtmp support hijack io apis for st-load. 2.0.42. 490 * v2.0, 2014-12-02, srs-librtmp support hijack io apis for st-load. 2.0.42.
490 * v2.0, 2014-12-01, for [#237](https://github.com/winlinvip/simple-rtmp-server/issues/237), refine syscall for recv, supports 1.5k clients. 2.0.41. 491 * v2.0, 2014-12-01, for [#237](https://github.com/winlinvip/simple-rtmp-server/issues/237), refine syscall for recv, supports 1.5k clients. 2.0.41.
@@ -703,47 +704,30 @@ Supported operating systems and hardware: @@ -703,47 +704,30 @@ Supported operating systems and hardware:
703 704
704 ## Performance 705 ## Performance
705 706
706 -Performance benchmark history, on virtual box: 707 +Performance benchmark history, on virtual box.
  708 +
  709 +### Play benchmark
  710 +
  711 +The play benchmark by st-load:
707 712
708 * 2013-11-28, SRS 0.5.0, 1.8k(1800)clients, 90%CPU, 41MB. [benchmark](https://github.com/winlinvip/simple-rtmp-server/commit/023e23bc8261bec15a70a7ae932098fb4f82b679) 713 * 2013-11-28, SRS 0.5.0, 1.8k(1800)clients, 90%CPU, 41MB. [benchmark](https://github.com/winlinvip/simple-rtmp-server/commit/023e23bc8261bec15a70a7ae932098fb4f82b679)
709 * 2014-07-12, SRS 0.9.156, 1.8k(1800)clients, 68%CPU, 38MB. [benchmark](https://github.com/winlinvip/simple-rtmp-server/commit/e2d273f4939348374bf9644df9d54c4293b39c1a) 714 * 2014-07-12, SRS 0.9.156, 1.8k(1800)clients, 68%CPU, 38MB. [benchmark](https://github.com/winlinvip/simple-rtmp-server/commit/e2d273f4939348374bf9644df9d54c4293b39c1a)
710 * 2014-07-12, SRS 0.9.156, 2.7k(2700)clients, 89%CPU, 61MB. [benchmark](https://github.com/winlinvip/simple-rtmp-server/commit/6d12280b7cc54c465b1caf8b1402149e77c4c7d9) 715 * 2014-07-12, SRS 0.9.156, 2.7k(2700)clients, 89%CPU, 61MB. [benchmark](https://github.com/winlinvip/simple-rtmp-server/commit/6d12280b7cc54c465b1caf8b1402149e77c4c7d9)
711 -* 2014-11-11, SRS 1.0.5, 2.7k(2700)clients, 85%CPU, 66MB. (1.0 equals 2.0.12) 716 +* 2014-11-11, SRS 1.0.5, 2.7k(2700)clients, 85%CPU, 66MB.
  717 +* 2014-11-11, SRS 2.0.12, 2.7k(2700)clients, 85%CPU, 66MB.
712 * 2014-11-12, SRS 2.0.14, 2.7k(2700)clients, 69%CPU, 59MB. 718 * 2014-11-12, SRS 2.0.14, 2.7k(2700)clients, 69%CPU, 59MB.
713 * 2014-11-12, SRS 2.0.14, 3.5k(3500)clients, 95%CPU, 78MB. 719 * 2014-11-12, SRS 2.0.14, 3.5k(3500)clients, 95%CPU, 78MB.
714 -* 2014-11-13, SRS 2.0.15, 6.0k(6000)clients, 82%CPU, 203MB. (500 publishers). 720 +* 2014-11-13, SRS 2.0.15, 6.0k(6000)clients, 82%CPU, 203MB.
715 * 2014-11-22, SRS 2.0.30, 7.5k(7500)clients, 87%CPU, 320MB. 721 * 2014-11-22, SRS 2.0.30, 7.5k(7500)clients, 87%CPU, 320MB.
716 -* 2014-12-01, SRS 2.0.41, 7.5k(7500)clients, 87%CPU, 320MB. (1500 publishers).  
717 722
718 -Latest benchmark(2014-07-12): 723 +* See also: [Performance for x86/x64 Test Guide](https://github.com/winlinvip/simple-rtmp-server/wiki/v1_CN_Performance)
  724 +* See also: [Performance for RaspberryPi](https://github.com/winlinvip/simple-rtmp-server/wiki/v1_CN_RaspberryPi)
719 725
720 -1. 300 connections, 150Mbps, 500kbps, CPU 5.7%, MEM 9208KB.  
721 -1. 600 connections, 300Mbps, 500kbps, CPU 18.3%, MEM 13MB.  
722 -1. 900 connections, 450Mbps, 500kbps, CPU 27.9%, MEM 20MB.  
723 -1. 1200 connections, 600Mbps, 500kbps, CPU 43.9%, MEM 26MB.  
724 -1. 1500 connections, 750Mbps, 500kbps, CPU 55.2%, MEM 32MB.  
725 -1. 1800 connections, 900Mbps, 500kbps, CPU 68.8%, MEM 38MB.  
726 -1. 2100 connections, 1050Mbps, 500kbps, CPU 75.7%, MEM 46MB.  
727 -1. 2400 connections, 1200Mbps, 500kbps, CPU 83.7%, MEM 54MB.  
728 -1. 2700 connections, 1350Mbps, 500kbps, CPU 89.9%, MEM 61MB. 726 +### Publish benchmark
729 727
730 -<pre>  
731 -[winlin@dev6 srs]$ dstat  
732 -----total-cpu-usage---- -dsk/total- ---net/lo-- ---paging-- ---system--  
733 -usr sys idl wai hiq siq| read writ| recv send| in out | int csw  
734 - 29 17 39 0 0 15| 0 5325B| 163M 163M| 0 0 |4331 3386  
735 - 30 16 38 0 0 16| 0 5325B| 160M 160M| 0 0 |4252 3332  
736 - 30 15 37 0 0 17| 0 7646B| 169M 169M| 0 0 |4015 2886  
737 - 30 17 36 0 0 17| 0 1638B| 197M 197M| 0 0 |4021 3037  
738 - 31 17 35 0 0 17| 0 410B| 204M 204M| 0 0 |4181 3243  
739 - 33 17 32 0 0 18| 0 2185B| 191M 191M| 0 0 |4305 3592  
740 - 31 15 36 0 0 18| 0 1229B| 127M 127M| 0 0 |4446 3822  
741 - 34 18 30 0 0 18| 0 0 | 231M 231M| 0 0 |4461 3691  
742 - 32 17 33 0 0 18| 0 410B| 169M 169M| 0 0 |4518 3788  
743 -</pre> 728 +The publish benchmark by st-load:
744 729
745 -* See also: [Performance for x86/x64 Test Guide](https://github.com/winlinvip/simple-rtmp-server/wiki/v1_CN_Performance)  
746 -* See also: [Performance for RaspberryPi](https://github.com/winlinvip/simple-rtmp-server/wiki/v1_CN_RaspberryPi) 730 +* 2014-12-03, SRS 1.0.10, 1k(1000) publishers, xx%CPU, xxMB.
747 731
748 ## Architecture 732 ## Architecture
749 733
@@ -230,11 +230,25 @@ SrsPublishRecvThread::SrsPublishRecvThread( @@ -230,11 +230,25 @@ SrsPublishRecvThread::SrsPublishRecvThread(
230 230
231 recv_error_code = ERROR_SUCCESS; 231 recv_error_code = ERROR_SUCCESS;
232 _nb_msgs = 0; 232 _nb_msgs = 0;
  233 + error = st_cond_new();
233 } 234 }
234 235
235 SrsPublishRecvThread::~SrsPublishRecvThread() 236 SrsPublishRecvThread::~SrsPublishRecvThread()
236 { 237 {
237 trd.stop(); 238 trd.stop();
  239 + st_cond_destroy(error);
  240 +}
  241 +
  242 +int SrsPublishRecvThread::wait(int timeout_ms)
  243 +{
  244 + if (recv_error_code != ERROR_SUCCESS) {
  245 + return recv_error_code;
  246 + }
  247 +
  248 + // ignore any return of cond wait.
  249 + st_cond_timedwait(error, timeout_ms * 1000);
  250 +
  251 + return ERROR_SUCCESS;
238 } 252 }
239 253
240 int64_t SrsPublishRecvThread::nb_msgs() 254 int64_t SrsPublishRecvThread::nb_msgs()
@@ -282,6 +296,10 @@ int SrsPublishRecvThread::handle(SrsMessage* msg) @@ -282,6 +296,10 @@ int SrsPublishRecvThread::handle(SrsMessage* msg)
282 void SrsPublishRecvThread::on_recv_error(int ret) 296 void SrsPublishRecvThread::on_recv_error(int ret)
283 { 297 {
284 recv_error_code = ret; 298 recv_error_code = ret;
  299 +
  300 + // when recv thread error, signal the conn thread to process it.
  301 + // @see https://github.com/winlinvip/simple-rtmp-server/issues/244
  302 + st_cond_signal(error);
285 } 303 }
286 304
287 void SrsPublishRecvThread::on_thread_start() 305 void SrsPublishRecvThread::on_thread_start()
@@ -294,4 +312,8 @@ void SrsPublishRecvThread::on_thread_stop() @@ -294,4 +312,8 @@ void SrsPublishRecvThread::on_thread_stop()
294 { 312 {
295 // we donot set the auto response to true, 313 // we donot set the auto response to true,
296 // for we donot set to false yet. 314 // for we donot set to false yet.
  315 +
  316 + // when thread stop, signal the conn thread which wait.
  317 + // @see https://github.com/winlinvip/simple-rtmp-server/issues/244
  318 + st_cond_signal(error);
297 } 319 }
@@ -142,14 +142,22 @@ private: @@ -142,14 +142,22 @@ private:
142 // the recv thread error code. 142 // the recv thread error code.
143 int recv_error_code; 143 int recv_error_code;
144 SrsRtmpConn* _conn; 144 SrsRtmpConn* _conn;
  145 + // the params for conn callback.
145 SrsSource* _source; 146 SrsSource* _source;
146 bool _is_fmle; 147 bool _is_fmle;
147 bool _is_edge; 148 bool _is_edge;
  149 + // the error timeout cond
  150 + // @see https://github.com/winlinvip/simple-rtmp-server/issues/244
  151 + st_cond_t error;
148 public: 152 public:
149 SrsPublishRecvThread(SrsRtmpServer* rtmp_sdk, int timeout_ms, 153 SrsPublishRecvThread(SrsRtmpServer* rtmp_sdk, int timeout_ms,
150 SrsRtmpConn* conn, SrsSource* source, bool is_fmle, bool is_edge); 154 SrsRtmpConn* conn, SrsSource* source, bool is_fmle, bool is_edge);
151 virtual ~SrsPublishRecvThread(); 155 virtual ~SrsPublishRecvThread();
152 public: 156 public:
  157 + /**
  158 + * wait for error for some timeout.
  159 + */
  160 + virtual int wait(int timeout_ms);
153 virtual int64_t nb_msgs(); 161 virtual int64_t nb_msgs();
154 virtual int error_code(); 162 virtual int error_code();
155 public: 163 public:
@@ -750,17 +750,15 @@ int SrsRtmpConn::do_publishing(SrsSource* source, SrsPublishRecvThread* trd) @@ -750,17 +750,15 @@ int SrsRtmpConn::do_publishing(SrsSource* source, SrsPublishRecvThread* trd)
750 750
751 int64_t nb_msgs = 0; 751 int64_t nb_msgs = 0;
752 while (true) { 752 while (true) {
753 - // use small loop to check the error code, interval = 30s/43 = 697ms.  
754 - for (int i = 0; i < 43; i++) {  
755 - st_usleep(SRS_CONSTS_RTMP_RECV_TIMEOUT_US / 43); 753 + // cond wait for error.
  754 + trd->wait(SRS_CONSTS_RTMP_RECV_TIMEOUT_US / 1000);
756 755
757 - // check the thread error code.  
758 - if ((ret = trd->error_code()) != ERROR_SUCCESS) {  
759 - if (!srs_is_client_gracefully_close(ret)) {  
760 - srs_error("recv thread failed. ret=%d", ret);  
761 - }  
762 - return ret; 756 + // check the thread error code.
  757 + if ((ret = trd->error_code()) != ERROR_SUCCESS) {
  758 + if (!srs_is_client_gracefully_close(ret)) {
  759 + srs_error("recv thread failed. ret=%d", ret);
763 } 760 }
  761 + return ret;
764 } 762 }
765 763
766 // when not got any messages, timeout. 764 // when not got any messages, timeout.