正在显示
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 |
-
请 注册 或 登录 后发表评论