winlin

fix the forwarder dead when st_thread interrupt at st_usleep, check thread->can_loop().

@@ -290,7 +290,7 @@ int SrsForwarder::forward() @@ -290,7 +290,7 @@ int SrsForwarder::forward()
290 290
291 SrsPithyPrint pithy_print(SRS_STAGE_FORWARDER); 291 SrsPithyPrint pithy_print(SRS_STAGE_FORWARDER);
292 292
293 - while (true) { 293 + while (pthread->can_loop()) {
294 // switch to other st-threads. 294 // switch to other st-threads.
295 st_usleep(0); 295 st_usleep(0);
296 296
@@ -102,6 +102,11 @@ void SrsThread::stop() @@ -102,6 +102,11 @@ void SrsThread::stop()
102 } 102 }
103 } 103 }
104 104
  105 +bool SrsThread::can_loop()
  106 +{
  107 + return loop;
  108 +}
  109 +
105 void SrsThread::thread_cycle() 110 void SrsThread::thread_cycle()
106 { 111 {
107 int ret = ERROR_SUCCESS; 112 int ret = ERROR_SUCCESS;
@@ -43,6 +43,23 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -43,6 +43,23 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
43 * when stop, the thread will interrupt the st_thread, 43 * when stop, the thread will interrupt the st_thread,
44 * which will cause the socket to return error and 44 * which will cause the socket to return error and
45 * terminate the cycle thread. 45 * terminate the cycle thread.
  46 +*
  47 +* when thread interrupt, the socket maybe not got EINT,
  48 +* espectially on st_usleep(), so the cycle must check the loop,
  49 +* when handler->cycle() has loop itself, for example:
  50 +* handler->cycle() is:
  51 +* while (true):
  52 +* st_usleep(0);
  53 +* if (read_from_socket(skt) < 0) break;
  54 +* if thread stop when read_from_socket, it's ok, the loop will break,
  55 +* but when thread stop interrupt the s_usleep(0), then the loop is
  56 +* death loop.
  57 +* in a word, the handler->cycle() must:
  58 +* handler->cycle() is:
  59 +* while (pthread->can_loop()):
  60 +* st_usleep(0);
  61 +* if (read_from_socket(skt) < 0) break;
  62 +* check the loop, then it works.
46 */ 63 */
47 class ISrsThreadHandler 64 class ISrsThreadHandler
48 { 65 {
@@ -90,6 +107,12 @@ public: @@ -90,6 +107,12 @@ public:
90 * @remark user can stop multiple times, ignore if already stopped. 107 * @remark user can stop multiple times, ignore if already stopped.
91 */ 108 */
92 virtual void stop(); 109 virtual void stop();
  110 + /**
  111 + * whether the thread should loop,
  112 + * used for handler->cycle() which has a loop method,
  113 + * to check this method, break if false.
  114 + */
  115 + virtual bool can_loop();
93 private: 116 private:
94 virtual void thread_cycle(); 117 virtual void thread_cycle();
95 static void* thread_fun(void* arg); 118 static void* thread_fun(void* arg);