正在显示
1 个修改的文件
包含
99 行增加
和
87 行删除
| @@ -32,93 +32,105 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -32,93 +32,105 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 32 | #include <srs_app_st.hpp> | 32 | #include <srs_app_st.hpp> |
| 33 | 33 | ||
| 34 | /** | 34 | /** |
| 35 | -* the handler for the thread, callback interface. | ||
| 36 | -* the thread model defines as: | ||
| 37 | -* handler->on_thread_start() | ||
| 38 | -* while loop: | ||
| 39 | -* handler->on_before_cycle() | ||
| 40 | -* handler->cycle() | ||
| 41 | -* handler->on_end_cycle() | ||
| 42 | -* if !loop then break for user stop thread. | ||
| 43 | -* sleep(CycleIntervalMilliseconds) | ||
| 44 | -* handler->on_thread_stop() | ||
| 45 | -* when stop, the thread will interrupt the st_thread, | ||
| 46 | -* which will cause the socket to return error and | ||
| 47 | -* terminate the cycle thread. | ||
| 48 | -* | ||
| 49 | -* Usage 1: stop by other thread. | ||
| 50 | -* user can create thread and stop then start again and again, | ||
| 51 | -* generally must provides a start and stop method, @see SrsIngester. | ||
| 52 | -* the step to create a thread stop by other thread: | ||
| 53 | -* 1. create SrsThread field, with joinable true. | ||
| 54 | -* 2. must use stop to stop and join the thread. | ||
| 55 | -* for example: | ||
| 56 | -* class SrsIngester : public ISrsThreadHandler { | ||
| 57 | -* public: SrsIngester() { pthread = new SrsThread("ingest", this, SRS_AUTO_INGESTER_SLEEP_US, true); } | ||
| 58 | -* public: virtual int start() { return pthread->start(); } | ||
| 59 | -* public: virtual void stop() { pthread->stop(); } | ||
| 60 | -* public: virtual int cycle() { | ||
| 61 | -* // check status, start ffmpeg when stopped. | ||
| 62 | -* } | ||
| 63 | -* }; | ||
| 64 | -* | ||
| 65 | -* Usage 2: stop by thread itself. | ||
| 66 | -* user can create thread which stop itself, | ||
| 67 | -* generally only need to provides a start method, | ||
| 68 | -* the object will destroy itself then terminate the thread, @see SrsConnection | ||
| 69 | -* 1. create SrsThread field, with joinable false. | ||
| 70 | -* 2. owner stop thread loop, destroy itself when thread stop. | ||
| 71 | -* for example: | ||
| 72 | -* class SrsConnection : public ISrsThreadHandler { | ||
| 73 | -* public: SrsConnection() { pthread = new SrsThread("conn", this, 0, false); } | ||
| 74 | -* public: virtual int start() { return pthread->start(); } | ||
| 75 | -* public: virtual int cycle() { | ||
| 76 | -* // serve client. | ||
| 77 | -* // set loop to stop to quit, stop thread itself. | ||
| 78 | -* pthread->stop_loop(); | ||
| 79 | -* } | ||
| 80 | -* public: virtual int on_thread_stop() { | ||
| 81 | -* // remove the connection in thread itself. | ||
| 82 | -* server->remove(this); | ||
| 83 | -* } | ||
| 84 | -* }; | ||
| 85 | -* | ||
| 86 | -* Usage 3: loop in the cycle method. | ||
| 87 | -* user can use loop code in the cycle method, @see SrsForwarder | ||
| 88 | -* 1. create SrsThread field, with or without joinable is ok. | ||
| 89 | -* 2. loop code in cycle method, check the can_loop() for thread to quit. | ||
| 90 | -* for example: | ||
| 91 | -* class SrsForwarder : public ISrsThreadHandler { | ||
| 92 | -* public: virtual int cycle() { | ||
| 93 | -* while (pthread->can_loop()) { | ||
| 94 | -* // read msgs from queue and forward to server. | ||
| 95 | -* } | ||
| 96 | -* } | ||
| 97 | -* }; | ||
| 98 | -* | ||
| 99 | -* @remark why should check can_loop() in cycle method? | ||
| 100 | -* when thread interrupt, the socket maybe not got EINT, | ||
| 101 | -* espectially on st_usleep(), so the cycle must check the loop, | ||
| 102 | -* when handler->cycle() has loop itself, for example: | ||
| 103 | -* while (true): | ||
| 104 | -* if (read_from_socket(skt) < 0) break; | ||
| 105 | -* if thread stop when read_from_socket, it's ok, the loop will break, | ||
| 106 | -* but when thread stop interrupt the s_usleep(0), then the loop is | ||
| 107 | -* death loop. | ||
| 108 | -* in a word, the handler->cycle() must: | ||
| 109 | -* while (pthread->can_loop()): | ||
| 110 | -* if (read_from_socket(skt) < 0) break; | ||
| 111 | -* check the loop, then it works. | ||
| 112 | -* | ||
| 113 | -* @remark why should use stop_loop() to terminate thread in itself? | ||
| 114 | -* in the thread itself, that is the cycle method, | ||
| 115 | -* if itself want to terminate the thread, should never use stop(), | ||
| 116 | -* but use stop_loop() to set the loop to false and terminate normally. | ||
| 117 | -* | ||
| 118 | -* @remark when should set the interval_us, and when not? | ||
| 119 | -* the cycle will invoke util cannot loop, eventhough the return code of cycle is error, | ||
| 120 | -* so the interval_us used to sleep for each cycle. | ||
| 121 | -*/ | 35 | + * the handler for the thread, callback interface. |
| 36 | + * the thread model defines as: | ||
| 37 | + * handler->on_thread_start() | ||
| 38 | + * while loop: | ||
| 39 | + * handler->on_before_cycle() | ||
| 40 | + * handler->cycle() | ||
| 41 | + * handler->on_end_cycle() | ||
| 42 | + * if !loop then break for user stop thread. | ||
| 43 | + * sleep(CycleIntervalMilliseconds) | ||
| 44 | + * handler->on_thread_stop() | ||
| 45 | + * when stop, the thread will interrupt the st_thread, | ||
| 46 | + * which will cause the socket to return error and | ||
| 47 | + * terminate the cycle thread. | ||
| 48 | + * | ||
| 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? | ||
| 112 | + * when thread interrupt, the socket maybe not got EINT, | ||
| 113 | + * espectially on st_usleep(), so the cycle must check the loop, | ||
| 114 | + * when handler->cycle() has loop itself, for example: | ||
| 115 | + * while (true): | ||
| 116 | + * if (read_from_socket(skt) < 0) break; | ||
| 117 | + * if thread stop when read_from_socket, it's ok, the loop will break, | ||
| 118 | + * but when thread stop interrupt the s_usleep(0), then the loop is | ||
| 119 | + * death loop. | ||
| 120 | + * in a word, the handler->cycle() must: | ||
| 121 | + * while (pthread->can_loop()): | ||
| 122 | + * if (read_from_socket(skt) < 0) break; | ||
| 123 | + * check the loop, then it works. | ||
| 124 | + * | ||
| 125 | + * @remark why should use stop_loop() to terminate thread in itself? | ||
| 126 | + * in the thread itself, that is the cycle method, | ||
| 127 | + * if itself want to terminate the thread, should never use stop(), | ||
| 128 | + * but use stop_loop() to set the loop to false and terminate normally. | ||
| 129 | + * | ||
| 130 | + * @remark when should set the interval_us, and when not? | ||
| 131 | + * 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. | ||
| 133 | + */ | ||
| 122 | class ISrsThreadHandler | 134 | class ISrsThreadHandler |
| 123 | { | 135 | { |
| 124 | public: | 136 | public: |
-
请 注册 或 登录 后发表评论