diff --git a/trunk/src/core/srs_core_forward.cpp b/trunk/src/core/srs_core_forward.cpp index 97e8b75e8..60a3541a7 100644 --- a/trunk/src/core/srs_core_forward.cpp +++ b/trunk/src/core/srs_core_forward.cpp @@ -290,7 +290,7 @@ int SrsForwarder::forward() SrsPithyPrint pithy_print(SRS_STAGE_FORWARDER); - while (true) { + while (pthread->can_loop()) { // switch to other st-threads. st_usleep(0); diff --git a/trunk/src/core/srs_core_thread.cpp b/trunk/src/core/srs_core_thread.cpp index b5670cccd..61e4fb5b8 100644 --- a/trunk/src/core/srs_core_thread.cpp +++ b/trunk/src/core/srs_core_thread.cpp @@ -102,6 +102,11 @@ void SrsThread::stop() } } +bool SrsThread::can_loop() +{ + return loop; +} + void SrsThread::thread_cycle() { int ret = ERROR_SUCCESS; diff --git a/trunk/src/core/srs_core_thread.hpp b/trunk/src/core/srs_core_thread.hpp index 8e649f760..940ba050c 100644 --- a/trunk/src/core/srs_core_thread.hpp +++ b/trunk/src/core/srs_core_thread.hpp @@ -43,6 +43,23 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * when stop, the thread will interrupt the st_thread, * which will cause the socket to return error and * terminate the cycle thread. +* +* when thread interrupt, the socket maybe not got EINT, +* espectially on st_usleep(), so the cycle must check the loop, +* when handler->cycle() has loop itself, for example: +* handler->cycle() is: +* while (true): +* st_usleep(0); +* if (read_from_socket(skt) < 0) break; +* if thread stop when read_from_socket, it's ok, the loop will break, +* but when thread stop interrupt the s_usleep(0), then the loop is +* death loop. +* in a word, the handler->cycle() must: +* handler->cycle() is: +* while (pthread->can_loop()): +* st_usleep(0); +* if (read_from_socket(skt) < 0) break; +* check the loop, then it works. */ class ISrsThreadHandler { @@ -90,6 +107,12 @@ public: * @remark user can stop multiple times, ignore if already stopped. */ virtual void stop(); + /** + * whether the thread should loop, + * used for handler->cycle() which has a loop method, + * to check this method, break if false. + */ + virtual bool can_loop(); private: virtual void thread_cycle(); static void* thread_fun(void* arg);