winlin

refine the thread to three category.

@@ -41,12 +41,11 @@ ISrsAsyncCallTask::~ISrsAsyncCallTask() @@ -41,12 +41,11 @@ ISrsAsyncCallTask::~ISrsAsyncCallTask()
41 41
42 SrsAsyncCallWorker::SrsAsyncCallWorker() 42 SrsAsyncCallWorker::SrsAsyncCallWorker()
43 { 43 {
44 - pthread = new SrsThread("async", this, SRS_AUTO_ASYNC_CALLBACL_SLEEP_US, true); 44 + pthread = new SrsReusableThread("async", this, SRS_AUTO_ASYNC_CALLBACL_SLEEP_US);
45 } 45 }
46 46
47 SrsAsyncCallWorker::~SrsAsyncCallWorker() 47 SrsAsyncCallWorker::~SrsAsyncCallWorker()
48 { 48 {
49 - stop();  
50 srs_freep(pthread); 49 srs_freep(pthread);
51 50
52 std::vector<ISrsAsyncCallTask*>::iterator it; 51 std::vector<ISrsAsyncCallTask*>::iterator it;
@@ -57,10 +57,10 @@ public: @@ -57,10 +57,10 @@ public:
57 * when worker call with the task, the worker will do it in isolate thread. 57 * when worker call with the task, the worker will do it in isolate thread.
58 * that is, the task is execute/call in async mode. 58 * that is, the task is execute/call in async mode.
59 */ 59 */
60 -class SrsAsyncCallWorker : public ISrsThreadHandler 60 +class SrsAsyncCallWorker : public ISrsReusableThreadHandler
61 { 61 {
62 private: 62 private:
63 - SrsThread* pthread; 63 + SrsReusableThread* pthread;
64 std::vector<ISrsAsyncCallTask*> tasks; 64 std::vector<ISrsAsyncCallTask*> tasks;
65 public: 65 public:
66 SrsAsyncCallWorker(); 66 SrsAsyncCallWorker();
@@ -70,6 +70,8 @@ public: @@ -70,6 +70,8 @@ public:
70 public: 70 public:
71 virtual int start(); 71 virtual int start();
72 virtual void stop(); 72 virtual void stop();
  73 +// interface ISrsReusableThreadHandler
  74 +public:
73 virtual int cycle(); 75 virtual int cycle();
74 }; 76 };
75 77
@@ -45,12 +45,17 @@ SrsConnection::SrsConnection(IConnectionManager* cm, st_netfd_t c) @@ -45,12 +45,17 @@ SrsConnection::SrsConnection(IConnectionManager* cm, st_netfd_t c)
45 // so we never use joinable. 45 // so we never use joinable.
46 // TODO: FIXME: maybe other thread need to stop it. 46 // TODO: FIXME: maybe other thread need to stop it.
47 // @see: https://github.com/simple-rtmp-server/srs/issues/78 47 // @see: https://github.com/simple-rtmp-server/srs/issues/78
48 - pthread = new SrsThread("conn", this, 0, false); 48 + pthread = new SrsOneCycleThread("conn", this);
49 } 49 }
50 50
51 SrsConnection::~SrsConnection() 51 SrsConnection::~SrsConnection()
52 { 52 {
53 - stop(); 53 + /**
  54 + * when delete the connection, stop the connection,
  55 + * close the underlayer socket, delete the thread.
  56 + */
  57 + srs_close_stfd(stfd);
  58 + srs_freep(pthread);
54 } 59 }
55 60
56 int SrsConnection::start() 61 int SrsConnection::start()
@@ -84,9 +89,6 @@ int SrsConnection::cycle() @@ -84,9 +89,6 @@ int SrsConnection::cycle()
84 srs_warn("client disconnect peer. ret=%d", ret); 89 srs_warn("client disconnect peer. ret=%d", ret);
85 } 90 }
86 91
87 - // set loop to stop to quit.  
88 - pthread->stop_loop();  
89 -  
90 return ERROR_SUCCESS; 92 return ERROR_SUCCESS;
91 } 93 }
92 94
@@ -101,10 +103,4 @@ int SrsConnection::srs_id() @@ -101,10 +103,4 @@ int SrsConnection::srs_id()
101 return id; 103 return id;
102 } 104 }
103 105
104 -void SrsConnection::stop()  
105 -{  
106 - srs_close_stfd(stfd);  
107 - srs_freep(pthread);  
108 -}  
109 -  
110 106
@@ -58,14 +58,14 @@ public: @@ -58,14 +58,14 @@ public:
58 * all connections accept from listener must extends from this base class, 58 * all connections accept from listener must extends from this base class,
59 * server will add the connection to manager, and delete it when remove. 59 * server will add the connection to manager, and delete it when remove.
60 */ 60 */
61 -class SrsConnection : public virtual ISrsThreadHandler, public virtual IKbpsDelta 61 +class SrsConnection : public virtual ISrsOneCycleThreadHandler, public virtual IKbpsDelta
62 { 62 {
63 private: 63 private:
64 /** 64 /**
65 * each connection start a green thread, 65 * each connection start a green thread,
66 * when thread stop, the connection will be delete by server. 66 * when thread stop, the connection will be delete by server.
67 */ 67 */
68 - SrsThread* pthread; 68 + SrsOneCycleThread* pthread;
69 /** 69 /**
70 * the id of connection. 70 * the id of connection.
71 */ 71 */
@@ -97,6 +97,8 @@ public: @@ -97,6 +97,8 @@ public:
97 * to remove the client by server->remove(this). 97 * to remove the client by server->remove(this).
98 */ 98 */
99 virtual int start(); 99 virtual int start();
  100 +// interface ISrsOneCycleThreadHandler
  101 +public:
100 /** 102 /**
101 * the thread cycle function, 103 * the thread cycle function,
102 * when serve connection completed, terminate the loop which will terminate the thread, 104 * when serve connection completed, terminate the loop which will terminate the thread,
@@ -119,12 +121,6 @@ protected: @@ -119,12 +121,6 @@ protected:
119 * for concrete connection to do the cycle. 121 * for concrete connection to do the cycle.
120 */ 122 */
121 virtual int do_cycle() = 0; 123 virtual int do_cycle() = 0;
122 -private:  
123 - /**  
124 - * when delete the connection, stop the connection,  
125 - * close the underlayer socket, delete the thread.  
126 - */  
127 - virtual void stop();  
128 }; 124 };
129 125
130 #endif 126 #endif
@@ -70,7 +70,7 @@ SrsEdgeIngester::SrsEdgeIngester() @@ -70,7 +70,7 @@ SrsEdgeIngester::SrsEdgeIngester()
70 origin_index = 0; 70 origin_index = 0;
71 stream_id = 0; 71 stream_id = 0;
72 stfd = NULL; 72 stfd = NULL;
73 - pthread = new SrsThread("edge-igs", this, SRS_EDGE_INGESTER_SLEEP_US, true); 73 + pthread = new SrsReusableThread("edge-igs", this, SRS_EDGE_INGESTER_SLEEP_US);
74 } 74 }
75 75
76 SrsEdgeIngester::~SrsEdgeIngester() 76 SrsEdgeIngester::~SrsEdgeIngester()
@@ -171,7 +171,7 @@ int SrsEdgeIngester::ingest() @@ -171,7 +171,7 @@ int SrsEdgeIngester::ingest()
171 SrsPithyPrint* pprint = SrsPithyPrint::create_edge(); 171 SrsPithyPrint* pprint = SrsPithyPrint::create_edge();
172 SrsAutoFree(SrsPithyPrint, pprint); 172 SrsAutoFree(SrsPithyPrint, pprint);
173 173
174 - while (pthread->can_loop()) { 174 + while (!pthread->interrupted()) {
175 pprint->elapse(); 175 pprint->elapse();
176 176
177 // pithy print 177 // pithy print
@@ -397,7 +397,7 @@ SrsEdgeForwarder::SrsEdgeForwarder() @@ -397,7 +397,7 @@ SrsEdgeForwarder::SrsEdgeForwarder()
397 origin_index = 0; 397 origin_index = 0;
398 stream_id = 0; 398 stream_id = 0;
399 stfd = NULL; 399 stfd = NULL;
400 - pthread = new SrsThread("edge-fwr", this, SRS_EDGE_FORWARDER_SLEEP_US, true); 400 + pthread = new SrsReusableThread("edge-fwr", this, SRS_EDGE_FORWARDER_SLEEP_US);
401 queue = new SrsMessageQueue(); 401 queue = new SrsMessageQueue();
402 send_error_code = ERROR_SUCCESS; 402 send_error_code = ERROR_SUCCESS;
403 } 403 }
@@ -489,7 +489,7 @@ int SrsEdgeForwarder::cycle() @@ -489,7 +489,7 @@ int SrsEdgeForwarder::cycle()
489 489
490 SrsMessageArray msgs(SYS_MAX_EDGE_SEND_MSGS); 490 SrsMessageArray msgs(SYS_MAX_EDGE_SEND_MSGS);
491 491
492 - while (pthread->can_loop()) { 492 + while (!pthread->interrupted()) {
493 if (send_error_code != ERROR_SUCCESS) { 493 if (send_error_code != ERROR_SUCCESS) {
494 st_usleep(SRS_EDGE_FORWARDER_ERROR_US); 494 st_usleep(SRS_EDGE_FORWARDER_ERROR_US);
495 continue; 495 continue;
@@ -75,7 +75,7 @@ enum SrsEdgeUserState @@ -75,7 +75,7 @@ enum SrsEdgeUserState
75 /** 75 /**
76 * edge used to ingest stream from origin. 76 * edge used to ingest stream from origin.
77 */ 77 */
78 -class SrsEdgeIngester : public ISrsThreadHandler 78 +class SrsEdgeIngester : public ISrsReusableThreadHandler
79 { 79 {
80 private: 80 private:
81 int stream_id; 81 int stream_id;
@@ -83,7 +83,7 @@ private: @@ -83,7 +83,7 @@ private:
83 SrsSource* _source; 83 SrsSource* _source;
84 SrsPlayEdge* _edge; 84 SrsPlayEdge* _edge;
85 SrsRequest* _req; 85 SrsRequest* _req;
86 - SrsThread* pthread; 86 + SrsReusableThread* pthread;
87 st_netfd_t stfd; 87 st_netfd_t stfd;
88 ISrsProtocolReaderWriter* io; 88 ISrsProtocolReaderWriter* io;
89 SrsKbps* kbps; 89 SrsKbps* kbps;
@@ -96,7 +96,7 @@ public: @@ -96,7 +96,7 @@ public:
96 virtual int initialize(SrsSource* source, SrsPlayEdge* edge, SrsRequest* req); 96 virtual int initialize(SrsSource* source, SrsPlayEdge* edge, SrsRequest* req);
97 virtual int start(); 97 virtual int start();
98 virtual void stop(); 98 virtual void stop();
99 -// interface ISrsThreadHandler 99 +// interface ISrsReusableThreadHandler
100 public: 100 public:
101 virtual int cycle(); 101 virtual int cycle();
102 private: 102 private:
@@ -110,7 +110,7 @@ private: @@ -110,7 +110,7 @@ private:
110 /** 110 /**
111 * edge used to forward stream to origin. 111 * edge used to forward stream to origin.
112 */ 112 */
113 -class SrsEdgeForwarder : public ISrsThreadHandler 113 +class SrsEdgeForwarder : public ISrsReusableThreadHandler
114 { 114 {
115 private: 115 private:
116 int stream_id; 116 int stream_id;
@@ -118,7 +118,7 @@ private: @@ -118,7 +118,7 @@ private:
118 SrsSource* _source; 118 SrsSource* _source;
119 SrsPublishEdge* _edge; 119 SrsPublishEdge* _edge;
120 SrsRequest* _req; 120 SrsRequest* _req;
121 - SrsThread* pthread; 121 + SrsReusableThread* pthread;
122 st_netfd_t stfd; 122 st_netfd_t stfd;
123 ISrsProtocolReaderWriter* io; 123 ISrsProtocolReaderWriter* io;
124 SrsKbps* kbps; 124 SrsKbps* kbps;
@@ -144,7 +144,7 @@ public: @@ -144,7 +144,7 @@ public:
144 virtual int initialize(SrsSource* source, SrsPublishEdge* edge, SrsRequest* req); 144 virtual int initialize(SrsSource* source, SrsPublishEdge* edge, SrsRequest* req);
145 virtual int start(); 145 virtual int start();
146 virtual void stop(); 146 virtual void stop();
147 -// interface ISrsThreadHandler 147 +// interface ISrsReusableThreadHandler
148 public: 148 public:
149 virtual int cycle(); 149 virtual int cycle();
150 public: 150 public:
@@ -44,7 +44,7 @@ static std::vector<std::string> _transcoded_url; @@ -44,7 +44,7 @@ static std::vector<std::string> _transcoded_url;
44 44
45 SrsEncoder::SrsEncoder() 45 SrsEncoder::SrsEncoder()
46 { 46 {
47 - pthread = new SrsThread("encoder", this, SRS_RTMP_ENCODER_SLEEP_US, true); 47 + pthread = new SrsReusableThread("encoder", this, SRS_RTMP_ENCODER_SLEEP_US);
48 pprint = SrsPithyPrint::create_encoder(); 48 pprint = SrsPithyPrint::create_encoder();
49 } 49 }
50 50
@@ -45,13 +45,13 @@ class SrsFFMPEG; @@ -45,13 +45,13 @@ class SrsFFMPEG;
45 * the encoder for a stream, 45 * the encoder for a stream,
46 * may use multiple ffmpegs to transcode the specified stream. 46 * may use multiple ffmpegs to transcode the specified stream.
47 */ 47 */
48 -class SrsEncoder : public ISrsThreadHandler 48 +class SrsEncoder : public ISrsReusableThreadHandler
49 { 49 {
50 private: 50 private:
51 std::string input_stream_name; 51 std::string input_stream_name;
52 std::vector<SrsFFMPEG*> ffmpegs; 52 std::vector<SrsFFMPEG*> ffmpegs;
53 private: 53 private:
54 - SrsThread* pthread; 54 + SrsReusableThread* pthread;
55 SrsPithyPrint* pprint; 55 SrsPithyPrint* pprint;
56 public: 56 public:
57 SrsEncoder(); 57 SrsEncoder();
@@ -59,7 +59,7 @@ public: @@ -59,7 +59,7 @@ public:
59 public: 59 public:
60 virtual int on_publish(SrsRequest* req); 60 virtual int on_publish(SrsRequest* req);
61 virtual void on_unpublish(); 61 virtual void on_unpublish();
62 -// interface ISrsThreadHandler. 62 +// interface ISrsReusableThreadHandler.
63 public: 63 public:
64 virtual int cycle(); 64 virtual int cycle();
65 virtual void on_thread_stop(); 65 virtual void on_thread_stop();
@@ -59,7 +59,7 @@ SrsForwarder::SrsForwarder(SrsSource* _source) @@ -59,7 +59,7 @@ SrsForwarder::SrsForwarder(SrsSource* _source)
59 kbps = new SrsKbps(); 59 kbps = new SrsKbps();
60 stream_id = 0; 60 stream_id = 0;
61 61
62 - pthread = new SrsThread("forward", this, SRS_FORWARDER_SLEEP_US, true); 62 + pthread = new SrsReusableThread("forward", this, SRS_FORWARDER_SLEEP_US);
63 queue = new SrsMessageQueue(); 63 queue = new SrsMessageQueue();
64 jitter = new SrsRtmpJitter(); 64 jitter = new SrsRtmpJitter();
65 65
@@ -407,7 +407,7 @@ int SrsForwarder::forward() @@ -407,7 +407,7 @@ int SrsForwarder::forward()
407 } 407 }
408 } 408 }
409 409
410 - while (pthread->can_loop()) { 410 + while (!pthread->interrupted()) {
411 pprint->elapse(); 411 pprint->elapse();
412 412
413 // read from client. 413 // read from client.
@@ -48,7 +48,7 @@ class SrsKbps; @@ -48,7 +48,7 @@ class SrsKbps;
48 * forward the stream to other servers. 48 * forward the stream to other servers.
49 */ 49 */
50 // TODO: FIXME: refine the error log, comments it. 50 // TODO: FIXME: refine the error log, comments it.
51 -class SrsForwarder : public ISrsThreadHandler 51 +class SrsForwarder : public ISrsReusableThreadHandler
52 { 52 {
53 private: 53 private:
54 // the ep to forward, server[:port]. 54 // the ep to forward, server[:port].
@@ -57,7 +57,7 @@ private: @@ -57,7 +57,7 @@ private:
57 int stream_id; 57 int stream_id;
58 private: 58 private:
59 st_netfd_t stfd; 59 st_netfd_t stfd;
60 - SrsThread* pthread; 60 + SrsReusableThread* pthread;
61 private: 61 private:
62 SrsSource* source; 62 SrsSource* source;
63 ISrsProtocolReaderWriter* io; 63 ISrsProtocolReaderWriter* io;
@@ -95,7 +95,7 @@ public: @@ -95,7 +95,7 @@ public:
95 * @param shared_video, directly ptr, copy it if need to save it. 95 * @param shared_video, directly ptr, copy it if need to save it.
96 */ 96 */
97 virtual int on_video(SrsSharedPtrMessage* shared_video); 97 virtual int on_video(SrsSharedPtrMessage* shared_video);
98 -// interface ISrsThreadHandler. 98 +// interface ISrsReusableThreadHandler.
99 public: 99 public:
100 virtual int cycle(); 100 virtual int cycle();
101 private: 101 private:
@@ -1157,12 +1157,11 @@ SrsStreamCache::SrsStreamCache(SrsSource* s, SrsRequest* r) @@ -1157,12 +1157,11 @@ SrsStreamCache::SrsStreamCache(SrsSource* s, SrsRequest* r)
1157 req = r->copy(); 1157 req = r->copy();
1158 source = s; 1158 source = s;
1159 queue = new SrsMessageQueue(true); 1159 queue = new SrsMessageQueue(true);
1160 - pthread = new SrsThread("http-stream", this, 0, false); 1160 + pthread = new SrsEndlessThread("http-stream", this);
1161 } 1161 }
1162 1162
1163 SrsStreamCache::~SrsStreamCache() 1163 SrsStreamCache::~SrsStreamCache()
1164 { 1164 {
1165 - pthread->stop();  
1166 srs_freep(pthread); 1165 srs_freep(pthread);
1167 1166
1168 srs_freep(queue); 1167 srs_freep(queue);
@@ -386,20 +386,20 @@ protected: @@ -386,20 +386,20 @@ protected:
386 * for example, the audio stream cache to make android(weixin) happy. 386 * for example, the audio stream cache to make android(weixin) happy.
387 * we start a thread to shrink the queue. 387 * we start a thread to shrink the queue.
388 */ 388 */
389 -class SrsStreamCache : public ISrsThreadHandler 389 +class SrsStreamCache : public ISrsEndlessThreadHandler
390 { 390 {
391 private: 391 private:
392 SrsMessageQueue* queue; 392 SrsMessageQueue* queue;
393 SrsSource* source; 393 SrsSource* source;
394 SrsRequest* req; 394 SrsRequest* req;
395 - SrsThread* pthread; 395 + SrsEndlessThread* pthread;
396 public: 396 public:
397 SrsStreamCache(SrsSource* s, SrsRequest* r); 397 SrsStreamCache(SrsSource* s, SrsRequest* r);
398 virtual ~SrsStreamCache(); 398 virtual ~SrsStreamCache();
399 public: 399 public:
400 virtual int start(); 400 virtual int start();
401 virtual int dump_cache(SrsConsumer* consumer); 401 virtual int dump_cache(SrsConsumer* consumer);
402 -// interface ISrsThreadHandler. 402 +// interface ISrsEndlessThreadHandler.
403 public: 403 public:
404 virtual int cycle(); 404 virtual int cycle();
405 }; 405 };
@@ -669,7 +669,7 @@ public: @@ -669,7 +669,7 @@ public:
669 virtual int hls_update_m3u8(SrsRequest* r, std::string m3u8); 669 virtual int hls_update_m3u8(SrsRequest* r, std::string m3u8);
670 virtual int hls_update_ts(SrsRequest* r, std::string uri, std::string ts); 670 virtual int hls_update_ts(SrsRequest* r, std::string uri, std::string ts);
671 virtual void unmount_hls(SrsRequest* r); 671 virtual void unmount_hls(SrsRequest* r);
672 -// interface ISrsThreadHandler. 672 +// interface ISrsReloadHandler.
673 public: 673 public:
674 virtual int on_reload_vhost_http_updated(); 674 virtual int on_reload_vhost_http_updated();
675 virtual int on_reload_vhost_http_remux_updated(); 675 virtual int on_reload_vhost_http_remux_updated();
@@ -55,7 +55,7 @@ SrsIngester::SrsIngester() @@ -55,7 +55,7 @@ SrsIngester::SrsIngester()
55 { 55 {
56 _srs_config->subscribe(this); 56 _srs_config->subscribe(this);
57 57
58 - pthread = new SrsThread("ingest", this, SRS_AUTO_INGESTER_SLEEP_US, true); 58 + pthread = new SrsReusableThread("ingest", this, SRS_AUTO_INGESTER_SLEEP_US);
59 pprint = SrsPithyPrint::create_ingester(); 59 pprint = SrsPithyPrint::create_ingester();
60 } 60 }
61 61
@@ -59,12 +59,12 @@ public: @@ -59,12 +59,12 @@ public:
59 * encode with FFMPEG(optional), 59 * encode with FFMPEG(optional),
60 * push to SRS(or any RTMP server) over RTMP. 60 * push to SRS(or any RTMP server) over RTMP.
61 */ 61 */
62 -class SrsIngester : public ISrsThreadHandler, public ISrsReloadHandler 62 +class SrsIngester : public ISrsReusableThreadHandler, public ISrsReloadHandler
63 { 63 {
64 private: 64 private:
65 std::vector<SrsIngesterFFMPEG*> ingesters; 65 std::vector<SrsIngesterFFMPEG*> ingesters;
66 private: 66 private:
67 - SrsThread* pthread; 67 + SrsReusableThread* pthread;
68 SrsPithyPrint* pprint; 68 SrsPithyPrint* pprint;
69 public: 69 public:
70 SrsIngester(); 70 SrsIngester();
@@ -72,7 +72,7 @@ public: @@ -72,7 +72,7 @@ public:
72 public: 72 public:
73 virtual int start(); 73 virtual int start();
74 virtual void stop(); 74 virtual void stop();
75 -// interface ISrsThreadHandler. 75 +// interface ISrsReusableThreadHandler.
76 public: 76 public:
77 virtual int cycle(); 77 virtual int cycle();
78 virtual void on_thread_stop(); 78 virtual void on_thread_stop();
@@ -79,7 +79,7 @@ SrsUdpListener::SrsUdpListener(ISrsUdpHandler* h, string i, int p) @@ -79,7 +79,7 @@ SrsUdpListener::SrsUdpListener(ISrsUdpHandler* h, string i, int p)
79 nb_buf = SRS_UDP_MAX_PACKET_SIZE; 79 nb_buf = SRS_UDP_MAX_PACKET_SIZE;
80 buf = new char[nb_buf]; 80 buf = new char[nb_buf];
81 81
82 - pthread = new SrsThread("udp", this, 0, true); 82 + pthread = new SrsReusableThread("udp", this);
83 } 83 }
84 84
85 SrsUdpListener::~SrsUdpListener() 85 SrsUdpListener::~SrsUdpListener()
@@ -157,7 +157,7 @@ int SrsUdpListener::cycle() @@ -157,7 +157,7 @@ int SrsUdpListener::cycle()
157 { 157 {
158 int ret = ERROR_SUCCESS; 158 int ret = ERROR_SUCCESS;
159 159
160 - while (pthread->can_loop()) { 160 + while (!pthread->interrupted()) {
161 // TODO: FIXME: support ipv6, @see man 7 ipv6 161 // TODO: FIXME: support ipv6, @see man 7 ipv6
162 sockaddr_in from; 162 sockaddr_in from;
163 int nb_from = sizeof(sockaddr_in); 163 int nb_from = sizeof(sockaddr_in);
@@ -190,7 +190,7 @@ SrsTcpListener::SrsTcpListener(ISrsTcpHandler* h, string i, int p) @@ -190,7 +190,7 @@ SrsTcpListener::SrsTcpListener(ISrsTcpHandler* h, string i, int p)
190 _fd = -1; 190 _fd = -1;
191 _stfd = NULL; 191 _stfd = NULL;
192 192
193 - pthread = new SrsThread("tcp", this, 0, true); 193 + pthread = new SrsReusableThread("tcp", this);
194 } 194 }
195 195
196 SrsTcpListener::~SrsTcpListener() 196 SrsTcpListener::~SrsTcpListener()
@@ -82,12 +82,12 @@ public: @@ -82,12 +82,12 @@ public:
82 /** 82 /**
83 * bind udp port, start thread to recv packet and handler it. 83 * bind udp port, start thread to recv packet and handler it.
84 */ 84 */
85 -class SrsUdpListener : public ISrsThreadHandler 85 +class SrsUdpListener : public ISrsReusableThreadHandler
86 { 86 {
87 private: 87 private:
88 int _fd; 88 int _fd;
89 st_netfd_t _stfd; 89 st_netfd_t _stfd;
90 - SrsThread* pthread; 90 + SrsReusableThread* pthread;
91 private: 91 private:
92 char* buf; 92 char* buf;
93 int nb_buf; 93 int nb_buf;
@@ -103,7 +103,7 @@ public: @@ -103,7 +103,7 @@ public:
103 virtual st_netfd_t stfd(); 103 virtual st_netfd_t stfd();
104 public: 104 public:
105 virtual int listen(); 105 virtual int listen();
106 -// interface ISrsThreadHandler. 106 +// interface ISrsReusableThreadHandler.
107 public: 107 public:
108 virtual int cycle(); 108 virtual int cycle();
109 }; 109 };
@@ -111,12 +111,12 @@ public: @@ -111,12 +111,12 @@ public:
111 /** 111 /**
112 * bind and listen tcp port, use handler to process the client. 112 * bind and listen tcp port, use handler to process the client.
113 */ 113 */
114 -class SrsTcpListener : public ISrsThreadHandler 114 +class SrsTcpListener : public ISrsReusableThreadHandler
115 { 115 {
116 private: 116 private:
117 int _fd; 117 int _fd;
118 st_netfd_t _stfd; 118 st_netfd_t _stfd;
119 - SrsThread* pthread; 119 + SrsReusableThread* pthread;
120 private: 120 private:
121 ISrsTcpHandler* handler; 121 ISrsTcpHandler* handler;
122 std::string ip; 122 std::string ip;
@@ -128,7 +128,7 @@ public: @@ -128,7 +128,7 @@ public:
128 virtual int fd(); 128 virtual int fd();
129 public: 129 public:
130 virtual int listen(); 130 virtual int listen();
131 -// interface ISrsThreadHandler. 131 +// interface ISrsReusableThreadHandler.
132 public: 132 public:
133 virtual int cycle(); 133 virtual int cycle();
134 }; 134 };
@@ -82,7 +82,7 @@ public: @@ -82,7 +82,7 @@ public:
82 virtual void trace(const char* tag, int context_id, const char* fmt, ...); 82 virtual void trace(const char* tag, int context_id, const char* fmt, ...);
83 virtual void warn(const char* tag, int context_id, const char* fmt, ...); 83 virtual void warn(const char* tag, int context_id, const char* fmt, ...);
84 virtual void error(const char* tag, int context_id, const char* fmt, ...); 84 virtual void error(const char* tag, int context_id, const char* fmt, ...);
85 -// interface ISrsThreadHandler. 85 +// interface ISrsReloadHandler.
86 public: 86 public:
87 virtual int on_reload_log_tank(); 87 virtual int on_reload_log_tank();
88 virtual int on_reload_log_level(); 88 virtual int on_reload_log_level();
@@ -50,7 +50,7 @@ SrsRecvThread::SrsRecvThread(ISrsMessageHandler* msg_handler, SrsRtmpServer* rtm @@ -50,7 +50,7 @@ SrsRecvThread::SrsRecvThread(ISrsMessageHandler* msg_handler, SrsRtmpServer* rtm
50 timeout = timeout_ms; 50 timeout = timeout_ms;
51 handler = msg_handler; 51 handler = msg_handler;
52 rtmp = rtmp_sdk; 52 rtmp = rtmp_sdk;
53 - trd = new SrsThread("recv", this, 0, true); 53 + trd = new SrsReusableThread("recv", this);
54 } 54 }
55 55
56 SrsRecvThread::~SrsRecvThread() 56 SrsRecvThread::~SrsRecvThread()
@@ -76,7 +76,7 @@ int SrsRecvThread::cycle() @@ -76,7 +76,7 @@ int SrsRecvThread::cycle()
76 { 76 {
77 int ret = ERROR_SUCCESS; 77 int ret = ERROR_SUCCESS;
78 78
79 - while (trd->can_loop()) { 79 + while (!trd->interrupted()) {
80 if (!handler->can_handle()) { 80 if (!handler->can_handle()) {
81 st_usleep(timeout * 1000); 81 st_usleep(timeout * 1000);
82 continue; 82 continue;
@@ -96,7 +96,7 @@ int SrsRecvThread::cycle() @@ -96,7 +96,7 @@ int SrsRecvThread::cycle()
96 } 96 }
97 97
98 // we use no timeout to recv, should never got any error. 98 // we use no timeout to recv, should never got any error.
99 - trd->stop_loop(); 99 + trd->interrupt();
100 100
101 // notice the handler got a recv error. 101 // notice the handler got a recv error.
102 handler->on_recv_error(ret); 102 handler->on_recv_error(ret);
@@ -111,7 +111,7 @@ int SrsRecvThread::cycle() @@ -111,7 +111,7 @@ int SrsRecvThread::cycle()
111 111
112 void SrsRecvThread::stop_loop() 112 void SrsRecvThread::stop_loop()
113 { 113 {
114 - trd->stop_loop(); 114 + trd->interrupt();
115 } 115 }
116 116
117 void SrsRecvThread::on_thread_start() 117 void SrsRecvThread::on_thread_start()
@@ -79,10 +79,10 @@ public: @@ -79,10 +79,10 @@ public:
79 /** 79 /**
80 * the recv thread, use message handler to handle each received message. 80 * the recv thread, use message handler to handle each received message.
81 */ 81 */
82 -class SrsRecvThread : public ISrsThreadHandler 82 +class SrsRecvThread : public ISrsReusableThreadHandler
83 { 83 {
84 protected: 84 protected:
85 - SrsThread* trd; 85 + SrsReusableThread* trd;
86 ISrsMessageHandler* handler; 86 ISrsMessageHandler* handler;
87 SrsRtmpServer* rtmp; 87 SrsRtmpServer* rtmp;
88 int timeout; 88 int timeout;
@@ -192,7 +192,7 @@ SrsRtspConn::SrsRtspConn(SrsRtspCaster* c, st_netfd_t fd, std::string o) @@ -192,7 +192,7 @@ SrsRtspConn::SrsRtspConn(SrsRtspCaster* c, st_netfd_t fd, std::string o)
192 stfd = fd; 192 stfd = fd;
193 skt = new SrsStSocket(fd); 193 skt = new SrsStSocket(fd);
194 rtsp = new SrsRtspStack(skt); 194 rtsp = new SrsRtspStack(skt);
195 - trd = new SrsThread("rtsp", this, 0, false); 195 + trd = new SrsOneCycleThread("rtsp", this);
196 196
197 req = NULL; 197 req = NULL;
198 io = NULL; 198 io = NULL;
@@ -210,7 +210,6 @@ SrsRtspConn::SrsRtspConn(SrsRtspCaster* c, st_netfd_t fd, std::string o) @@ -210,7 +210,6 @@ SrsRtspConn::SrsRtspConn(SrsRtspCaster* c, st_netfd_t fd, std::string o)
210 SrsRtspConn::~SrsRtspConn() 210 SrsRtspConn::~SrsRtspConn()
211 { 211 {
212 srs_close_stfd(stfd); 212 srs_close_stfd(stfd);
213 - trd->stop();  
214 213
215 srs_freep(video_rtp); 214 srs_freep(video_rtp);
216 srs_freep(audio_rtp); 215 srs_freep(audio_rtp);
@@ -219,7 +218,9 @@ SrsRtspConn::~SrsRtspConn() @@ -219,7 +218,9 @@ SrsRtspConn::~SrsRtspConn()
219 srs_freep(skt); 218 srs_freep(skt);
220 srs_freep(rtsp); 219 srs_freep(rtsp);
221 220
222 - close(); 221 + srs_freep(client);
  222 + srs_freep(io);
  223 + srs_freep(req);
223 224
224 srs_freep(vjitter); 225 srs_freep(vjitter);
225 srs_freep(ajitter); 226 srs_freep(ajitter);
@@ -412,9 +413,6 @@ int SrsRtspConn::cycle() @@ -412,9 +413,6 @@ int SrsRtspConn::cycle()
412 srs_warn("client disconnect peer. ret=%d", ret); 413 srs_warn("client disconnect peer. ret=%d", ret);
413 } 414 }
414 415
415 - // terminate thread in the thread cycle itself.  
416 - trd->stop_loop();  
417 -  
418 return ERROR_SUCCESS; 416 return ERROR_SUCCESS;
419 } 417 }
420 418
@@ -763,14 +761,6 @@ int SrsRtspConn::connect_app(string ep_server, string ep_port) @@ -763,14 +761,6 @@ int SrsRtspConn::connect_app(string ep_server, string ep_port)
763 return ret; 761 return ret;
764 } 762 }
765 763
766 -void SrsRtspConn::close()  
767 -{  
768 - srs_freep(client);  
769 - srs_freep(io);  
770 - srs_freep(req);  
771 - srs_close_stfd(stfd);  
772 -}  
773 -  
774 SrsRtspCaster::SrsRtspCaster(SrsConfDirective* c) 764 SrsRtspCaster::SrsRtspCaster(SrsConfDirective* c)
775 { 765 {
776 // TODO: FIXME: support reload. 766 // TODO: FIXME: support reload.
@@ -113,7 +113,7 @@ public: @@ -113,7 +113,7 @@ public:
113 /** 113 /**
114 * the rtsp connection serve the fd. 114 * the rtsp connection serve the fd.
115 */ 115 */
116 -class SrsRtspConn : public ISrsThreadHandler 116 +class SrsRtspConn : public ISrsOneCycleThreadHandler
117 { 117 {
118 private: 118 private:
119 std::string output_template; 119 std::string output_template;
@@ -136,7 +136,7 @@ private: @@ -136,7 +136,7 @@ private:
136 SrsStSocket* skt; 136 SrsStSocket* skt;
137 SrsRtspStack* rtsp; 137 SrsRtspStack* rtsp;
138 SrsRtspCaster* caster; 138 SrsRtspCaster* caster;
139 - SrsThread* trd; 139 + SrsOneCycleThread* trd;
140 private: 140 private:
141 SrsRequest* req; 141 SrsRequest* req;
142 SrsStSocket* io; 142 SrsStSocket* io;
@@ -163,7 +163,7 @@ private: @@ -163,7 +163,7 @@ private:
163 // internal methods 163 // internal methods
164 public: 164 public:
165 virtual int on_rtp_packet(SrsRtpPacket* pkt, int stream_id); 165 virtual int on_rtp_packet(SrsRtpPacket* pkt, int stream_id);
166 -// interface ISrsThreadHandler 166 +// interface ISrsOneCycleThreadHandler
167 public: 167 public:
168 virtual int cycle(); 168 virtual int cycle();
169 virtual void on_thread_stop(); 169 virtual void on_thread_stop();
@@ -182,8 +182,6 @@ private: @@ -182,8 +182,6 @@ private:
182 // @remark ignore when not connected, reconnect when disconnected. 182 // @remark ignore when not connected, reconnect when disconnected.
183 virtual int connect(); 183 virtual int connect();
184 virtual int connect_app(std::string ep_server, std::string ep_port); 184 virtual int connect_app(std::string ep_server, std::string ep_port);
185 - // close the connected io and rtmp to ready to be re-connect.  
186 - virtual void close();  
187 }; 185 };
188 186
189 /** 187 /**
@@ -367,13 +367,12 @@ SrsSignalManager::SrsSignalManager(SrsServer* server) @@ -367,13 +367,12 @@ SrsSignalManager::SrsSignalManager(SrsServer* server)
367 367
368 _server = server; 368 _server = server;
369 sig_pipe[0] = sig_pipe[1] = -1; 369 sig_pipe[0] = sig_pipe[1] = -1;
370 - pthread = new SrsThread("signal", this, 0, true); 370 + pthread = new SrsEndlessThread("signal", this);
371 signal_read_stfd = NULL; 371 signal_read_stfd = NULL;
372 } 372 }
373 373
374 SrsSignalManager::~SrsSignalManager() 374 SrsSignalManager::~SrsSignalManager()
375 { 375 {
376 - pthread->stop();  
377 srs_freep(pthread); 376 srs_freep(pthread);
378 377
379 srs_close_stfd(signal_read_stfd); 378 srs_close_stfd(signal_read_stfd);
@@ -179,7 +179,7 @@ public: @@ -179,7 +179,7 @@ public:
179 * convert signal to io, 179 * convert signal to io,
180 * @see: st-1.9/docs/notes.html 180 * @see: st-1.9/docs/notes.html
181 */ 181 */
182 -class SrsSignalManager : public ISrsThreadHandler 182 +class SrsSignalManager : public ISrsEndlessThreadHandler
183 { 183 {
184 private: 184 private:
185 /* Per-process pipe which is used as a signal queue. */ 185 /* Per-process pipe which is used as a signal queue. */
@@ -188,14 +188,14 @@ private: @@ -188,14 +188,14 @@ private:
188 st_netfd_t signal_read_stfd; 188 st_netfd_t signal_read_stfd;
189 private: 189 private:
190 SrsServer* _server; 190 SrsServer* _server;
191 - SrsThread* pthread; 191 + SrsEndlessThread* pthread;
192 public: 192 public:
193 SrsSignalManager(SrsServer* server); 193 SrsSignalManager(SrsServer* server);
194 virtual ~SrsSignalManager(); 194 virtual ~SrsSignalManager();
195 public: 195 public:
196 virtual int initialize(); 196 virtual int initialize();
197 virtual int start(); 197 virtual int start();
198 -// interface ISrsThreadHandler. 198 +// interface ISrsEndlessThreadHandler.
199 public: 199 public:
200 virtual int cycle(); 200 virtual int cycle();
201 private: 201 private:
@@ -26,36 +26,37 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -26,36 +26,37 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 #include <srs_kernel_error.hpp> 26 #include <srs_kernel_error.hpp>
27 #include <srs_kernel_log.hpp> 27 #include <srs_kernel_log.hpp>
28 28
29 -ISrsThreadHandler::ISrsThreadHandler()  
30 -{  
31 -} 29 +namespace internal {
  30 + ISrsThreadHandler::ISrsThreadHandler()
  31 + {
  32 + }
32 33
33 -ISrsThreadHandler::~ISrsThreadHandler()  
34 -{  
35 -} 34 + ISrsThreadHandler::~ISrsThreadHandler()
  35 + {
  36 + }
36 37
37 -void ISrsThreadHandler::on_thread_start()  
38 -{  
39 -} 38 + void ISrsThreadHandler::on_thread_start()
  39 + {
  40 + }
40 41
41 -int ISrsThreadHandler::on_before_cycle()  
42 -{ 42 + int ISrsThreadHandler::on_before_cycle()
  43 + {
43 int ret = ERROR_SUCCESS; 44 int ret = ERROR_SUCCESS;
44 return ret; 45 return ret;
45 -} 46 + }
46 47
47 -int ISrsThreadHandler::on_end_cycle()  
48 -{ 48 + int ISrsThreadHandler::on_end_cycle()
  49 + {
49 int ret = ERROR_SUCCESS; 50 int ret = ERROR_SUCCESS;
50 return ret; 51 return ret;
51 -} 52 + }
52 53
53 -void ISrsThreadHandler::on_thread_stop()  
54 -{  
55 -} 54 + void ISrsThreadHandler::on_thread_stop()
  55 + {
  56 + }
56 57
57 -SrsThread::SrsThread(const char* name, ISrsThreadHandler* thread_handler, int64_t interval_us, bool joinable)  
58 -{ 58 + SrsThread::SrsThread(const char* name, ISrsThreadHandler* thread_handler, int64_t interval_us, bool joinable)
  59 + {
59 _name = name; 60 _name = name;
60 handler = thread_handler; 61 handler = thread_handler;
61 cycle_interval_us = interval_us; 62 cycle_interval_us = interval_us;
@@ -71,20 +72,20 @@ SrsThread::SrsThread(const char* name, ISrsThreadHandler* thread_handler, int64_ @@ -71,20 +72,20 @@ SrsThread::SrsThread(const char* name, ISrsThreadHandler* thread_handler, int64_
71 // @see https://github.com/simple-rtmp-server/srs/issues/110 72 // @see https://github.com/simple-rtmp-server/srs/issues/110
72 // thread will set _cid, callback on_thread_start(), then wait for the can_run signal. 73 // thread will set _cid, callback on_thread_start(), then wait for the can_run signal.
73 can_run = false; 74 can_run = false;
74 -} 75 + }
75 76
76 -SrsThread::~SrsThread()  
77 -{ 77 + SrsThread::~SrsThread()
  78 + {
78 stop(); 79 stop();
79 -} 80 + }
80 81
81 -int SrsThread::cid()  
82 -{ 82 + int SrsThread::cid()
  83 + {
83 return _cid; 84 return _cid;
84 -} 85 + }
85 86
86 -int SrsThread::start()  
87 -{ 87 + int SrsThread::start()
  88 + {
88 int ret = ERROR_SUCCESS; 89 int ret = ERROR_SUCCESS;
89 90
90 if(tid) { 91 if(tid) {
@@ -110,10 +111,10 @@ int SrsThread::start() @@ -110,10 +111,10 @@ int SrsThread::start()
110 can_run = true; 111 can_run = true;
111 112
112 return ret; 113 return ret;
113 -} 114 + }
114 115
115 -void SrsThread::stop()  
116 -{ 116 + void SrsThread::stop()
  117 + {
117 if (tid) { 118 if (tid) {
118 loop = false; 119 loop = false;
119 120
@@ -145,20 +146,20 @@ void SrsThread::stop() @@ -145,20 +146,20 @@ void SrsThread::stop()
145 146
146 tid = NULL; 147 tid = NULL;
147 } 148 }
148 -} 149 + }
149 150
150 -bool SrsThread::can_loop()  
151 -{ 151 + bool SrsThread::can_loop()
  152 + {
152 return loop; 153 return loop;
153 -} 154 + }
154 155
155 -void SrsThread::stop_loop()  
156 -{ 156 + void SrsThread::stop_loop()
  157 + {
157 loop = false; 158 loop = false;
158 -} 159 + }
159 160
160 -void SrsThread::thread_cycle()  
161 -{ 161 + void SrsThread::thread_cycle()
  162 + {
162 int ret = ERROR_SUCCESS; 163 int ret = ERROR_SUCCESS;
163 164
164 _srs_context->generate_id(); 165 _srs_context->generate_id();
@@ -198,7 +199,7 @@ void SrsThread::thread_cycle() @@ -198,7 +199,7 @@ void SrsThread::thread_cycle()
198 } 199 }
199 srs_info("thread %s on end cycle success", _name); 200 srs_info("thread %s on end cycle success", _name);
200 201
201 -failed: 202 + failed:
202 if (!loop) { 203 if (!loop) {
203 break; 204 break;
204 } 205 }
@@ -215,10 +216,10 @@ failed: @@ -215,10 +216,10 @@ failed:
215 216
216 handler->on_thread_stop(); 217 handler->on_thread_stop();
217 srs_info("thread %s cycle finished", _name); 218 srs_info("thread %s cycle finished", _name);
218 -} 219 + }
219 220
220 -void* SrsThread::thread_fun(void* arg)  
221 -{ 221 + void* SrsThread::thread_fun(void* arg)
  222 + {
222 SrsThread* obj = (SrsThread*)arg; 223 SrsThread* obj = (SrsThread*)arg;
223 srs_assert(obj); 224 srs_assert(obj);
224 225
@@ -227,5 +228,135 @@ void* SrsThread::thread_fun(void* arg) @@ -227,5 +228,135 @@ void* SrsThread::thread_fun(void* arg)
227 st_thread_exit(NULL); 228 st_thread_exit(NULL);
228 229
229 return NULL; 230 return NULL;
  231 + }
  232 +}
  233 +
  234 +ISrsEndlessThreadHandler::ISrsEndlessThreadHandler()
  235 +{
  236 +}
  237 +
  238 +ISrsEndlessThreadHandler::~ISrsEndlessThreadHandler()
  239 +{
  240 +}
  241 +
  242 +SrsEndlessThread::SrsEndlessThread(const char* n, ISrsEndlessThreadHandler* h)
  243 +{
  244 + handler = h;
  245 + pthread = new internal::SrsThread(n, this, 0, false);
  246 +}
  247 +
  248 +SrsEndlessThread::~SrsEndlessThread()
  249 +{
  250 + pthread->stop();
  251 + srs_freep(pthread);
  252 +}
  253 +
  254 +int SrsEndlessThread::start()
  255 +{
  256 + return pthread->start();
  257 +}
  258 +
  259 +int SrsEndlessThread::cycle()
  260 +{
  261 + return handler->cycle();
230 } 262 }
231 263
  264 +ISrsOneCycleThreadHandler::ISrsOneCycleThreadHandler()
  265 +{
  266 +}
  267 +
  268 +ISrsOneCycleThreadHandler::~ISrsOneCycleThreadHandler()
  269 +{
  270 +}
  271 +
  272 +void ISrsOneCycleThreadHandler::on_thread_stop()
  273 +{
  274 +}
  275 +
  276 +SrsOneCycleThread::SrsOneCycleThread(const char* n, ISrsOneCycleThreadHandler* h)
  277 +{
  278 + handler = h;
  279 + pthread = new internal::SrsThread(n, this, 0, false);
  280 +}
  281 +
  282 +SrsOneCycleThread::~SrsOneCycleThread()
  283 +{
  284 + pthread->stop();
  285 + srs_freep(pthread);
  286 +}
  287 +
  288 +int SrsOneCycleThread::start()
  289 +{
  290 + return pthread->start();
  291 +}
  292 +
  293 +int SrsOneCycleThread::cycle()
  294 +{
  295 + int ret = handler->cycle();
  296 + pthread->stop_loop();
  297 + return ret;
  298 +}
  299 +
  300 +void SrsOneCycleThread::on_thread_stop()
  301 +{
  302 + handler->on_thread_stop();
  303 +}
  304 +
  305 +ISrsReusableThreadHandler::ISrsReusableThreadHandler()
  306 +{
  307 +}
  308 +
  309 +ISrsReusableThreadHandler::~ISrsReusableThreadHandler()
  310 +{
  311 +}
  312 +
  313 +void ISrsReusableThreadHandler::on_thread_stop()
  314 +{
  315 +}
  316 +
  317 +SrsReusableThread::SrsReusableThread(const char* n, ISrsReusableThreadHandler* h, int64_t interval_us)
  318 +{
  319 + handler = h;
  320 + pthread = new internal::SrsThread(n, this, interval_us, true);
  321 +}
  322 +
  323 +SrsReusableThread::~SrsReusableThread()
  324 +{
  325 + pthread->stop();
  326 + srs_freep(pthread);
  327 +}
  328 +
  329 +int SrsReusableThread::start()
  330 +{
  331 + return pthread->start();
  332 +}
  333 +
  334 +void SrsReusableThread::stop()
  335 +{
  336 + pthread->stop();
  337 +}
  338 +
  339 +int SrsReusableThread::cid()
  340 +{
  341 + return pthread->cid();
  342 +}
  343 +
  344 +void SrsReusableThread::interrupt()
  345 +{
  346 + pthread->stop_loop();
  347 +}
  348 +
  349 +bool SrsReusableThread::interrupted()
  350 +{
  351 + return !pthread->can_loop();
  352 +}
  353 +
  354 +int SrsReusableThread::cycle()
  355 +{
  356 + return handler->cycle();
  357 +}
  358 +
  359 +void SrsReusableThread::on_thread_stop()
  360 +{
  361 + handler->on_thread_stop();
  362 +}
@@ -31,7 +31,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -31,7 +31,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 31
32 #include <srs_app_st.hpp> 32 #include <srs_app_st.hpp>
33 33
34 -/** 34 +// the internal classes, user should never use it.
  35 +// user should use the public classes at the bellow:
  36 +// @see SrsEndlessThread, SrsOneCycleThread, SrsReusableThread
  37 +namespace internal {
  38 + /**
35 * the handler for the thread, callback interface. 39 * the handler for the thread, callback interface.
36 * the thread model defines as: 40 * the thread model defines as:
37 * handler->on_thread_start() 41 * handler->on_thread_start()
@@ -46,68 +50,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -46,68 +50,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
46 * which will cause the socket to return error and 50 * which will cause the socket to return error and
47 * terminate the cycle thread. 51 * terminate the cycle thread.
48 * 52 *
49 - * Usage 1: loop thread never quit.  
50 - * user can create thread always running util server terminate.  
51 - * the step to create a thread never stop:  
52 - * 1. create SrsThread field, with joinable false.  
53 - * for example:  
54 - * class SrsStreamCache : public ISrsThreadHandler {  
55 - * public: SrsStreamCache() { pthread = new SrsThread("http-stream", this, SRS_AUTO_STREAM_SLEEP_US, false); }  
56 - * public: virtual int cycle() {  
57 - * // check status, start ffmpeg when stopped.  
58 - * }  
59 - * }  
60 - *  
61 - * Usage 2: stop by other thread.  
62 - * user can create thread and stop then start again and again,  
63 - * generally must provides a start and stop method, @see SrsIngester.  
64 - * the step to create a thread stop by other thread:  
65 - * 1. create SrsThread field, with joinable true.  
66 - * 2. must use stop to stop and join the thread.  
67 - * for example:  
68 - * class SrsIngester : public ISrsThreadHandler {  
69 - * public: SrsIngester() { pthread = new SrsThread("ingest", this, SRS_AUTO_INGESTER_SLEEP_US, true); }  
70 - * public: virtual int start() { return pthread->start(); }  
71 - * public: virtual void stop() { pthread->stop(); }  
72 - * public: virtual int cycle() {  
73 - * // check status, start ffmpeg when stopped.  
74 - * }  
75 - * };  
76 - *  
77 - * Usage 3: stop by thread itself.  
78 - * user can create thread which stop itself,  
79 - * generally only need to provides a start method,  
80 - * the object will destroy itself then terminate the thread, @see SrsConnection  
81 - * 1. create SrsThread field, with joinable false.  
82 - * 2. owner stop thread loop, destroy itself when thread stop.  
83 - * for example:  
84 - * class SrsConnection : public ISrsThreadHandler {  
85 - * public: SrsConnection() { pthread = new SrsThread("conn", this, 0, false); }  
86 - * public: virtual int start() { return pthread->start(); }  
87 - * public: virtual int cycle() {  
88 - * // serve client.  
89 - * // set loop to stop to quit, stop thread itself.  
90 - * pthread->stop_loop();  
91 - * }  
92 - * public: virtual int on_thread_stop() {  
93 - * // remove the connection in thread itself.  
94 - * server->remove(this);  
95 - * }  
96 - * };  
97 - *  
98 - * Usage 4: loop in the cycle method.  
99 - * user can use loop code in the cycle method, @see SrsForwarder  
100 - * 1. create SrsThread field, with or without joinable is ok.  
101 - * 2. loop code in cycle method, check the can_loop() for thread to quit.  
102 - * for example:  
103 - * class SrsForwarder : public ISrsThreadHandler {  
104 - * public: virtual int cycle() {  
105 - * while (pthread->can_loop()) {  
106 - * // read msgs from queue and forward to server.  
107 - * }  
108 - * }  
109 - * };  
110 - *  
111 * @remark why should check can_loop() in cycle method? 53 * @remark why should check can_loop() in cycle method?
112 * when thread interrupt, the socket maybe not got EINT, 54 * when thread interrupt, the socket maybe not got EINT,
113 * espectially on st_usleep(), so the cycle must check the loop, 55 * espectially on st_usleep(), so the cycle must check the loop,
@@ -131,26 +73,26 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -131,26 +73,26 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
131 * the cycle will invoke util cannot loop, eventhough the return code of cycle is error, 73 * the cycle will invoke util cannot loop, eventhough the return code of cycle is error,
132 * so the interval_us used to sleep for each cycle. 74 * so the interval_us used to sleep for each cycle.
133 */ 75 */
134 -class ISrsThreadHandler  
135 -{  
136 -public: 76 + class ISrsThreadHandler
  77 + {
  78 + public:
137 ISrsThreadHandler(); 79 ISrsThreadHandler();
138 virtual ~ISrsThreadHandler(); 80 virtual ~ISrsThreadHandler();
139 -public: 81 + public:
140 virtual void on_thread_start(); 82 virtual void on_thread_start();
141 virtual int on_before_cycle(); 83 virtual int on_before_cycle();
142 virtual int cycle() = 0; 84 virtual int cycle() = 0;
143 virtual int on_end_cycle(); 85 virtual int on_end_cycle();
144 virtual void on_thread_stop(); 86 virtual void on_thread_stop();
145 -}; 87 + };
146 88
147 -/**  
148 -* provides servies from st_thread_t,  
149 -* for common thread usage.  
150 -*/  
151 -class SrsThread  
152 -{  
153 -private: 89 + /**
  90 + * provides servies from st_thread_t,
  91 + * for common thread usage.
  92 + */
  93 + class SrsThread
  94 + {
  95 + private:
154 st_thread_t tid; 96 st_thread_t tid;
155 int _cid; 97 int _cid;
156 bool loop; 98 bool loop;
@@ -158,10 +100,10 @@ private: @@ -158,10 +100,10 @@ private:
158 bool really_terminated; 100 bool really_terminated;
159 bool _joinable; 101 bool _joinable;
160 const char* _name; 102 const char* _name;
161 -private: 103 + private:
162 ISrsThreadHandler* handler; 104 ISrsThreadHandler* handler;
163 int64_t cycle_interval_us; 105 int64_t cycle_interval_us;
164 -public: 106 + public:
165 /** 107 /**
166 * initialize the thread. 108 * initialize the thread.
167 * @param name, human readable name for st debug. 109 * @param name, human readable name for st debug.
@@ -178,7 +120,7 @@ public: @@ -178,7 +120,7 @@ public:
178 */ 120 */
179 SrsThread(const char* name, ISrsThreadHandler* thread_handler, int64_t interval_us, bool joinable); 121 SrsThread(const char* name, ISrsThreadHandler* thread_handler, int64_t interval_us, bool joinable);
180 virtual ~SrsThread(); 122 virtual ~SrsThread();
181 -public: 123 + public:
182 /** 124 /**
183 * get the context id. @see: ISrsThreadContext.get_id(). 125 * get the context id. @see: ISrsThreadContext.get_id().
184 * used for parent thread to get the id. 126 * used for parent thread to get the id.
@@ -198,7 +140,7 @@ public: @@ -198,7 +140,7 @@ public:
198 * @remark user can stop multiple times, ignore if already stopped. 140 * @remark user can stop multiple times, ignore if already stopped.
199 */ 141 */
200 virtual void stop(); 142 virtual void stop();
201 -public: 143 + public:
202 /** 144 /**
203 * whether the thread should loop, 145 * whether the thread should loop,
204 * used for handler->cycle() which has a loop method, 146 * used for handler->cycle() which has a loop method,
@@ -211,9 +153,189 @@ public: @@ -211,9 +153,189 @@ public:
211 * this stop loop method only set loop to false. 153 * this stop loop method only set loop to false.
212 */ 154 */
213 virtual void stop_loop(); 155 virtual void stop_loop();
214 -private: 156 + private:
215 virtual void thread_cycle(); 157 virtual void thread_cycle();
216 static void* thread_fun(void* arg); 158 static void* thread_fun(void* arg);
  159 + };
  160 +}
  161 +
  162 +/**
  163 + * the endless thread is a loop thread never quit.
  164 + * user can create thread always running util server terminate.
  165 + * the step to create a thread never stop:
  166 + * 1. create SrsEndlessThread field.
  167 + * for example:
  168 + * class SrsStreamCache : public ISrsEndlessThreadHandler {
  169 + * public: SrsStreamCache() { pthread = new SrsEndlessThread("http-stream", this); }
  170 + * public: virtual int cycle() {
  171 + * // do some work never end.
  172 + * }
  173 + * }
  174 + * @remark user must use block method in cycle method, for example, sleep or socket io.
  175 + */
  176 +class ISrsEndlessThreadHandler
  177 +{
  178 +public:
  179 + ISrsEndlessThreadHandler();
  180 + virtual ~ISrsEndlessThreadHandler();
  181 +public:
  182 + /**
  183 + * the cycle method for the common thread.
  184 + * @remark user must use block method in cycle method, for example, sleep or socket io.
  185 + */
  186 + virtual int cycle() = 0;
  187 +};
  188 +class SrsEndlessThread : public internal::ISrsThreadHandler
  189 +{
  190 +private:
  191 + internal::SrsThread* pthread;
  192 + ISrsEndlessThreadHandler* handler;
  193 +public:
  194 + SrsEndlessThread(const char* n, ISrsEndlessThreadHandler* h);
  195 + virtual ~SrsEndlessThread();
  196 +public:
  197 + /**
  198 + * for the endless thread, never quit.
  199 + */
  200 + virtual int start();
  201 +// interface internal::ISrsThreadHandler
  202 +public:
  203 + virtual int cycle();
  204 +};
  205 +
  206 +/**
  207 + * the one cycle thread is a thread do the cycle only one time,
  208 + * that is, the thread will quit when return from the cycle.
  209 + * user can create thread which stop itself,
  210 + * generally only need to provides a start method,
  211 + * the object will destroy itself then terminate the thread, @see SrsConnection
  212 + * 1. create SrsThread field
  213 + * 2. the thread quit when return from cycle.
  214 + * for example:
  215 + * class SrsConnection : public ISrsOneCycleThreadHandler {
  216 + * public: SrsConnection() { pthread = new SrsOneCycleThread("conn", this); }
  217 + * public: virtual int start() { return pthread->start(); }
  218 + * public: virtual int cycle() {
  219 + * // serve client.
  220 + * // set loop to stop to quit, stop thread itself.
  221 + * pthread->stop_loop();
  222 + * }
  223 + * public: virtual void on_thread_stop() {
  224 + * // remove the connection in thread itself.
  225 + * server->remove(this);
  226 + * }
  227 + * };
  228 + */
  229 +class ISrsOneCycleThreadHandler
  230 +{
  231 +public:
  232 + ISrsOneCycleThreadHandler();
  233 + virtual ~ISrsOneCycleThreadHandler();
  234 +public:
  235 + /**
  236 + * the cycle method for the one cycle thread.
  237 + */
  238 + virtual int cycle() = 0;
  239 + /**
  240 + * when thread stop, the handler can do cleanup.
  241 + * @remark this method is optional, handler can ignore it.
  242 + */
  243 + virtual void on_thread_stop();
  244 +};
  245 +class SrsOneCycleThread : public internal::ISrsThreadHandler
  246 +{
  247 +private:
  248 + internal::SrsThread* pthread;
  249 + ISrsOneCycleThreadHandler* handler;
  250 +public:
  251 + SrsOneCycleThread(const char* n, ISrsOneCycleThreadHandler* h);
  252 + virtual ~SrsOneCycleThread();
  253 +public:
  254 + /**
  255 + * for the one cycle thread, quit when cycle return.
  256 + */
  257 + virtual int start();
  258 +// interface internal::ISrsThreadHandler
  259 +public:
  260 + virtual int cycle();
  261 + virtual void on_thread_stop();
  262 +};
  263 +
  264 +/**
  265 + * the reuse thread is a thread stop and start by other thread.
  266 + * user can create thread and stop then start again and again,
  267 + * generally must provides a start and stop method, @see SrsIngester.
  268 + * the step to create a thread stop by other thread:
  269 + * 1. create SrsThread field, with joinable true.
  270 + * 2. must use stop to stop and join the thread.
  271 + * for example:
  272 + * class SrsIngester : public ISrsThreadHandler {
  273 + * public: SrsIngester() { pthread = new SrsThread("ingest", this, SRS_AUTO_INGESTER_SLEEP_US, true); }
  274 + * public: virtual int start() { return pthread->start(); }
  275 + * public: virtual void stop() { pthread->stop(); }
  276 + * public: virtual int cycle() {
  277 + * // check status, start ffmpeg when stopped.
  278 + * }
  279 + * };
  280 + */
  281 +class ISrsReusableThreadHandler
  282 +{
  283 +public:
  284 + ISrsReusableThreadHandler();
  285 + virtual ~ISrsReusableThreadHandler();
  286 +public:
  287 + /**
  288 + * the cycle method for the one cycle thread.
  289 + * @remark when the cycle has its inner loop, it must check whether
  290 + * the thread is interrupted.
  291 + */
  292 + virtual int cycle() = 0;
  293 + /**
  294 + * when thread stop, the handler can do cleanup.
  295 + * @remark this method is optional, handler can ignore it.
  296 + */
  297 + virtual void on_thread_stop();
  298 +};
  299 +class SrsReusableThread : public internal::ISrsThreadHandler
  300 +{
  301 +private:
  302 + internal::SrsThread* pthread;
  303 + ISrsReusableThreadHandler* handler;
  304 +public:
  305 + SrsReusableThread(const char* n, ISrsReusableThreadHandler* h, int64_t interval_us = 0);
  306 + virtual ~SrsReusableThread();
  307 +public:
  308 + /**
  309 + * for the reusable thread, start and stop by user.
  310 + */
  311 + virtual int start();
  312 + /**
  313 + * stop the thread, wait for the thread to terminate.
  314 + * @remark user can stop multiple times, ignore if already stopped.
  315 + */
  316 + virtual void stop();
  317 +public:
  318 + /**
  319 + * get the context id. @see: ISrsThreadContext.get_id().
  320 + * used for parent thread to get the id.
  321 + * @remark when start thread, parent thread will block and wait for this id ready.
  322 + */
  323 + virtual int cid();
  324 + /**
  325 + * interrupt the thread to stop loop.
  326 + * we only set the loop flag to false, not really interrupt the thread.
  327 + */
  328 + virtual void interrupt();
  329 + /**
  330 + * whether the thread is interrupted,
  331 + * for the cycle has its loop, the inner loop should quit when thread
  332 + * is interrupted.
  333 + */
  334 + virtual bool interrupted();
  335 +// interface internal::ISrsThreadHandler
  336 +public:
  337 + virtual int cycle();
  338 + virtual void on_thread_stop();
217 }; 339 };
218 340
219 #endif 341 #endif