正在显示
2 个修改的文件
包含
130 行增加
和
63 行删除
| @@ -26,95 +26,69 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -26,95 +26,69 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 26 | #include <srs_protocol_rtmp.hpp> | 26 | #include <srs_protocol_rtmp.hpp> |
| 27 | #include <srs_protocol_stack.hpp> | 27 | #include <srs_protocol_stack.hpp> |
| 28 | 28 | ||
| 29 | -SrsQueueRecvThread::SrsQueueRecvThread(SrsRtmpServer* rtmp_sdk) | 29 | +ISrsMessageHandler::ISrsMessageHandler() |
| 30 | { | 30 | { |
| 31 | - rtmp = rtmp_sdk; | ||
| 32 | - trd = new SrsThread(this, 0, true); | ||
| 33 | } | 31 | } |
| 34 | 32 | ||
| 35 | -SrsQueueRecvThread::~SrsQueueRecvThread() | 33 | +ISrsMessageHandler::~ISrsMessageHandler() |
| 36 | { | 34 | { |
| 37 | - // stop recv thread. | ||
| 38 | - stop(); | ||
| 39 | - | ||
| 40 | - // destroy the thread. | ||
| 41 | - srs_freep(trd); | ||
| 42 | - | ||
| 43 | - // clear all messages. | ||
| 44 | - std::vector<SrsMessage*>::iterator it; | ||
| 45 | - for (it = queue.begin(); it != queue.end(); ++it) { | ||
| 46 | - SrsMessage* msg = *it; | ||
| 47 | - srs_freep(msg); | ||
| 48 | - } | ||
| 49 | - queue.clear(); | ||
| 50 | } | 35 | } |
| 51 | 36 | ||
| 52 | -bool SrsQueueRecvThread::empty() | 37 | +SrsRecvThread::SrsRecvThread(ISrsMessageHandler* msg_handler, SrsRtmpServer* rtmp_sdk) |
| 53 | { | 38 | { |
| 54 | - return queue.empty(); | 39 | + handler = msg_handler; |
| 40 | + rtmp = rtmp_sdk; | ||
| 41 | + trd = new SrsThread(this, 0, true); | ||
| 55 | } | 42 | } |
| 56 | 43 | ||
| 57 | -int SrsQueueRecvThread::size() | 44 | +SrsRecvThread::~SrsRecvThread() |
| 58 | { | 45 | { |
| 59 | - return (int)queue.size(); | ||
| 60 | -} | 46 | + // stop recv thread. |
| 47 | + stop(); | ||
| 61 | 48 | ||
| 62 | -SrsMessage* SrsQueueRecvThread::pump() | ||
| 63 | -{ | ||
| 64 | - srs_assert(!queue.empty()); | ||
| 65 | - | ||
| 66 | - SrsMessage* msg = *queue.begin(); | ||
| 67 | - | ||
| 68 | - queue.erase(queue.begin()); | ||
| 69 | - | ||
| 70 | - return msg; | 49 | + // destroy the thread. |
| 50 | + srs_freep(trd); | ||
| 71 | } | 51 | } |
| 72 | 52 | ||
| 73 | -int SrsQueueRecvThread::start() | 53 | +int SrsRecvThread::start() |
| 74 | { | 54 | { |
| 75 | return trd->start(); | 55 | return trd->start(); |
| 76 | } | 56 | } |
| 77 | 57 | ||
| 78 | -void SrsQueueRecvThread::stop() | 58 | +void SrsRecvThread::stop() |
| 79 | { | 59 | { |
| 80 | trd->stop(); | 60 | trd->stop(); |
| 81 | } | 61 | } |
| 82 | 62 | ||
| 83 | -int SrsQueueRecvThread::cycle() | 63 | +int SrsRecvThread::cycle() |
| 84 | { | 64 | { |
| 85 | int ret = ERROR_SUCCESS; | 65 | int ret = ERROR_SUCCESS; |
| 86 | - | ||
| 87 | - // we only recv one message and then process it, | ||
| 88 | - // for the message may cause the thread to stop, | ||
| 89 | - // when stop, the thread is freed, so the messages | ||
| 90 | - // are dropped. | ||
| 91 | - if (!queue.empty()) { | 66 | + |
| 67 | + if (!handler->can_handle()) { | ||
| 92 | st_usleep(SRS_CONSTS_RTMP_PULSE_TIMEOUT_US); | 68 | st_usleep(SRS_CONSTS_RTMP_PULSE_TIMEOUT_US); |
| 93 | return ret; | 69 | return ret; |
| 94 | } | 70 | } |
| 95 | - | 71 | + |
| 96 | SrsMessage* msg = NULL; | 72 | SrsMessage* msg = NULL; |
| 97 | - | 73 | + |
| 98 | if ((ret = rtmp->recv_message(&msg)) != ERROR_SUCCESS) { | 74 | if ((ret = rtmp->recv_message(&msg)) != ERROR_SUCCESS) { |
| 99 | if (!srs_is_client_gracefully_close(ret)) { | 75 | if (!srs_is_client_gracefully_close(ret)) { |
| 100 | srs_error("recv client control message failed. ret=%d", ret); | 76 | srs_error("recv client control message failed. ret=%d", ret); |
| 101 | } | 77 | } |
| 102 | - | 78 | + |
| 103 | // we use no timeout to recv, should never got any error. | 79 | // we use no timeout to recv, should never got any error. |
| 104 | trd->stop_loop(); | 80 | trd->stop_loop(); |
| 105 | - | 81 | + |
| 106 | return ret; | 82 | return ret; |
| 107 | } | 83 | } |
| 108 | srs_verbose("play loop recv message. ret=%d", ret); | 84 | srs_verbose("play loop recv message. ret=%d", ret); |
| 109 | - | ||
| 110 | - // put into queue, the send thread will get and process it, | ||
| 111 | - // @see SrsRtmpConn::process_play_control_msg | ||
| 112 | - queue.push_back(msg); | ||
| 113 | - | 85 | + |
| 86 | + handler->handle(msg); | ||
| 87 | + | ||
| 114 | return ret; | 88 | return ret; |
| 115 | } | 89 | } |
| 116 | 90 | ||
| 117 | -void SrsQueueRecvThread::on_thread_start() | 91 | +void SrsRecvThread::on_thread_start() |
| 118 | { | 92 | { |
| 119 | // the multiple messages writev improve performance large, | 93 | // the multiple messages writev improve performance large, |
| 120 | // but the timeout recv will cause 33% sys call performance, | 94 | // but the timeout recv will cause 33% sys call performance, |
| @@ -122,19 +96,75 @@ void SrsQueueRecvThread::on_thread_start() | @@ -122,19 +96,75 @@ void SrsQueueRecvThread::on_thread_start() | ||
| 122 | // @see https://github.com/winlinvip/simple-rtmp-server/issues/194 | 96 | // @see https://github.com/winlinvip/simple-rtmp-server/issues/194 |
| 123 | // @see: https://github.com/winlinvip/simple-rtmp-server/issues/217 | 97 | // @see: https://github.com/winlinvip/simple-rtmp-server/issues/217 |
| 124 | rtmp->set_recv_timeout(ST_UTIME_NO_TIMEOUT); | 98 | rtmp->set_recv_timeout(ST_UTIME_NO_TIMEOUT); |
| 125 | - | ||
| 126 | - // disable the protocol auto response, | 99 | + |
| 100 | + // disable the protocol auto response, | ||
| 127 | // for the isolate recv thread should never send any messages. | 101 | // for the isolate recv thread should never send any messages. |
| 128 | rtmp->set_auto_response(false); | 102 | rtmp->set_auto_response(false); |
| 129 | } | 103 | } |
| 130 | 104 | ||
| 131 | -void SrsQueueRecvThread::on_thread_stop() | 105 | +void SrsRecvThread::on_thread_stop() |
| 132 | { | 106 | { |
| 133 | // enable the protocol auto response, | 107 | // enable the protocol auto response, |
| 134 | // for the isolate recv thread terminated. | 108 | // for the isolate recv thread terminated. |
| 135 | rtmp->set_auto_response(true); | 109 | rtmp->set_auto_response(true); |
| 136 | - | 110 | + |
| 137 | // reset the timeout to pulse mode. | 111 | // reset the timeout to pulse mode. |
| 138 | rtmp->set_recv_timeout(SRS_CONSTS_RTMP_PULSE_TIMEOUT_US); | 112 | rtmp->set_recv_timeout(SRS_CONSTS_RTMP_PULSE_TIMEOUT_US); |
| 139 | } | 113 | } |
| 140 | 114 | ||
| 115 | +SrsQueueRecvThread::SrsQueueRecvThread(SrsRtmpServer* rtmp_sdk) | ||
| 116 | + : SrsRecvThread(this, rtmp_sdk) | ||
| 117 | +{ | ||
| 118 | +} | ||
| 119 | + | ||
| 120 | +SrsQueueRecvThread::~SrsQueueRecvThread() | ||
| 121 | +{ | ||
| 122 | + stop(); | ||
| 123 | + | ||
| 124 | + // clear all messages. | ||
| 125 | + std::vector<SrsMessage*>::iterator it; | ||
| 126 | + for (it = queue.begin(); it != queue.end(); ++it) { | ||
| 127 | + SrsMessage* msg = *it; | ||
| 128 | + srs_freep(msg); | ||
| 129 | + } | ||
| 130 | + queue.clear(); | ||
| 131 | +} | ||
| 132 | + | ||
| 133 | +bool SrsQueueRecvThread::empty() | ||
| 134 | +{ | ||
| 135 | + return queue.empty(); | ||
| 136 | +} | ||
| 137 | + | ||
| 138 | +int SrsQueueRecvThread::size() | ||
| 139 | +{ | ||
| 140 | + return (int)queue.size(); | ||
| 141 | +} | ||
| 142 | + | ||
| 143 | +SrsMessage* SrsQueueRecvThread::pump() | ||
| 144 | +{ | ||
| 145 | + srs_assert(!queue.empty()); | ||
| 146 | + | ||
| 147 | + SrsMessage* msg = *queue.begin(); | ||
| 148 | + | ||
| 149 | + queue.erase(queue.begin()); | ||
| 150 | + | ||
| 151 | + return msg; | ||
| 152 | +} | ||
| 153 | + | ||
| 154 | +bool SrsQueueRecvThread::can_handle() | ||
| 155 | +{ | ||
| 156 | + // we only recv one message and then process it, | ||
| 157 | + // for the message may cause the thread to stop, | ||
| 158 | + // when stop, the thread is freed, so the messages | ||
| 159 | + // are dropped. | ||
| 160 | + return empty(); | ||
| 161 | +} | ||
| 162 | + | ||
| 163 | +int SrsQueueRecvThread::handle(SrsMessage* msg) | ||
| 164 | +{ | ||
| 165 | + // put into queue, the send thread will get and process it, | ||
| 166 | + // @see SrsRtmpConn::process_play_control_msg | ||
| 167 | + queue.push_back(msg); | ||
| 168 | + | ||
| 169 | + return ERROR_SUCCESS; | ||
| 170 | +} |
| @@ -38,16 +38,57 @@ class SrsRtmpServer; | @@ -38,16 +38,57 @@ class SrsRtmpServer; | ||
| 38 | class SrsMessage; | 38 | class SrsMessage; |
| 39 | 39 | ||
| 40 | /** | 40 | /** |
| 41 | + * for the recv thread to handle the message. | ||
| 42 | + */ | ||
| 43 | +class ISrsMessageHandler | ||
| 44 | +{ | ||
| 45 | +public: | ||
| 46 | + ISrsMessageHandler(); | ||
| 47 | + virtual ~ISrsMessageHandler(); | ||
| 48 | +public: | ||
| 49 | + /** | ||
| 50 | + * whether the handler can handle, | ||
| 51 | + * for example, when queue recv handler got an message, | ||
| 52 | + * it wait the user to process it, then the recv thread | ||
| 53 | + * never recv message util the handler is ok. | ||
| 54 | + */ | ||
| 55 | + virtual bool can_handle() = 0; | ||
| 56 | + /** | ||
| 57 | + * process the received message. | ||
| 58 | + */ | ||
| 59 | + virtual int handle(SrsMessage* msg) = 0; | ||
| 60 | +}; | ||
| 61 | + | ||
| 62 | +/** | ||
| 63 | + * the recv thread, use message handler to handle each received message. | ||
| 64 | + */ | ||
| 65 | +class SrsRecvThread : public ISrsThreadHandler | ||
| 66 | +{ | ||
| 67 | +protected: | ||
| 68 | + SrsThread* trd; | ||
| 69 | + ISrsMessageHandler* handler; | ||
| 70 | + SrsRtmpServer* rtmp; | ||
| 71 | +public: | ||
| 72 | + SrsRecvThread(ISrsMessageHandler* msg_handler, SrsRtmpServer* rtmp_sdk); | ||
| 73 | + virtual ~SrsRecvThread(); | ||
| 74 | +public: | ||
| 75 | + virtual int start(); | ||
| 76 | + virtual void stop(); | ||
| 77 | + virtual int cycle(); | ||
| 78 | +public: | ||
| 79 | + virtual void on_thread_start(); | ||
| 80 | + virtual void on_thread_stop(); | ||
| 81 | +}; | ||
| 82 | + | ||
| 83 | +/** | ||
| 41 | * the recv thread used to replace the timeout recv, | 84 | * the recv thread used to replace the timeout recv, |
| 42 | * which hurt performance for the epoll_ctrl is frequently used. | 85 | * which hurt performance for the epoll_ctrl is frequently used. |
| 43 | * @see: SrsRtmpConn::playing | 86 | * @see: SrsRtmpConn::playing |
| 44 | * @see: https://github.com/winlinvip/simple-rtmp-server/issues/217 | 87 | * @see: https://github.com/winlinvip/simple-rtmp-server/issues/217 |
| 45 | */ | 88 | */ |
| 46 | -class SrsQueueRecvThread : public ISrsThreadHandler | 89 | +class SrsQueueRecvThread : virtual public ISrsMessageHandler, virtual public SrsRecvThread |
| 47 | { | 90 | { |
| 48 | private: | 91 | private: |
| 49 | - SrsThread* trd; | ||
| 50 | - SrsRtmpServer* rtmp; | ||
| 51 | std::vector<SrsMessage*> queue; | 92 | std::vector<SrsMessage*> queue; |
| 52 | public: | 93 | public: |
| 53 | SrsQueueRecvThread(SrsRtmpServer* rtmp_sdk); | 94 | SrsQueueRecvThread(SrsRtmpServer* rtmp_sdk); |
| @@ -57,12 +98,8 @@ public: | @@ -57,12 +98,8 @@ public: | ||
| 57 | virtual int size(); | 98 | virtual int size(); |
| 58 | virtual SrsMessage* pump(); | 99 | virtual SrsMessage* pump(); |
| 59 | public: | 100 | public: |
| 60 | - virtual int start(); | ||
| 61 | - virtual void stop(); | ||
| 62 | - virtual int cycle(); | ||
| 63 | -public: | ||
| 64 | - virtual void on_thread_start(); | ||
| 65 | - virtual void on_thread_stop(); | 101 | + virtual bool can_handle(); |
| 102 | + virtual int handle(SrsMessage* msg); | ||
| 66 | }; | 103 | }; |
| 67 | 104 | ||
| 68 | #endif | 105 | #endif |
-
请 注册 或 登录 后发表评论