1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-03-09 15:49:59 +00:00

Merge SRS2

This commit is contained in:
winlin 2017-05-01 16:44:14 +08:00
commit f97260be1d
8 changed files with 119 additions and 2 deletions

View file

@ -215,6 +215,8 @@ Please select your language:
### V2 changes ### V2 changes
* v2.0, 2017-05-01, Fix [#865][bug #865], shouldn't remove ts/m3u8 when hls_dispose disabled. 2.0.242
* v2.0, 2017-04-30, Fix [#636][bug #636], FD leak for requesting empty HTTP stream. 2.0.241
* v2.0, 2017-04-23, Fix [#851][bug #851], HTTP API support number of video frames for FPS. 2.0.240 * v2.0, 2017-04-23, Fix [#851][bug #851], HTTP API support number of video frames for FPS. 2.0.240
* <strong>v2.0, 2017-04-18, [2.0 release1(2.0.239)][r2.0r1] released. 86515 lines.</strong> * <strong>v2.0, 2017-04-18, [2.0 release1(2.0.239)][r2.0r1] released. 86515 lines.</strong>
* v2.0, 2017-04-18, Fix [#848][bug #848], crash at HTTP fast buffer grow. 2.0.239 * v2.0, 2017-04-18, Fix [#848][bug #848], crash at HTTP fast buffer grow. 2.0.239
@ -1399,6 +1401,8 @@ Winlin
[bug #844]: https://github.com/ossrs/srs/issues/844 [bug #844]: https://github.com/ossrs/srs/issues/844
[bug #848]: https://github.com/ossrs/srs/issues/848 [bug #848]: https://github.com/ossrs/srs/issues/848
[bug #851]: https://github.com/ossrs/srs/issues/851 [bug #851]: https://github.com/ossrs/srs/issues/851
[bug #636]: https://github.com/ossrs/srs/issues/636
[bug #865]: https://github.com/ossrs/srs/issues/865
[bug #xxxxxxxxxx]: https://github.com/ossrs/srs/issues/xxxxxxxxxx [bug #xxxxxxxxxx]: https://github.com/ossrs/srs/issues/xxxxxxxxxx
[bug #735]: https://github.com/ossrs/srs/issues/735 [bug #735]: https://github.com/ossrs/srs/issues/735

View file

@ -992,6 +992,13 @@ void SrsHls::dispose()
on_unpublish(); on_unpublish();
} }
// Ignore when hls_dispose disabled.
// @see https://github.com/ossrs/srs/issues/865
int hls_dispose = _srs_config->get_hls_dispose(req->vhost);
if (!hls_dispose) {
return;
}
controller->dispose(); controller->dispose();
} }

View file

@ -212,6 +212,19 @@ SrsResponseOnlyHttpConn::~SrsResponseOnlyHttpConn()
{ {
} }
int SrsResponseOnlyHttpConn::pop_message(ISrsHttpMessage** preq)
{
int ret = ERROR_SUCCESS;
SrsStSocket skt(stfd);
if ((ret = parser->parse_message(&skt, this, preq)) != ERROR_SUCCESS) {
return ret;
}
return ret;
}
int SrsResponseOnlyHttpConn::on_got_http_message(ISrsHttpMessage* msg) int SrsResponseOnlyHttpConn::on_got_http_message(ISrsHttpMessage* msg)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;

View file

@ -60,7 +60,7 @@ class SrsHttpStaticServer;
*/ */
class SrsHttpConn : public SrsConnection class SrsHttpConn : public SrsConnection
{ {
private: protected:
SrsHttpParser* parser; SrsHttpParser* parser;
ISrsHttpServeMux* http_mux; ISrsHttpServeMux* http_mux;
SrsHttpCorsMux* cors; SrsHttpCorsMux* cors;
@ -101,6 +101,13 @@ class SrsResponseOnlyHttpConn : public SrsHttpConn
public: public:
SrsResponseOnlyHttpConn(IConnectionManager* cm, st_netfd_t fd, ISrsHttpServeMux* m, std::string cip); SrsResponseOnlyHttpConn(IConnectionManager* cm, st_netfd_t fd, ISrsHttpServeMux* m, std::string cip);
virtual ~SrsResponseOnlyHttpConn(); virtual ~SrsResponseOnlyHttpConn();
public:
// Directly read a HTTP request message.
// It's exported for HTTP stream, such as HTTP FLV, only need to write to client when
// serving it, but we need to start a thread to read message to detect whether FD is closed.
// @see https://github.com/ossrs/srs/issues/636#issuecomment-298208427
// @remark Should only used in HTTP-FLV streaming connection.
virtual int pop_message(ISrsHttpMessage** preq);
public: public:
virtual int on_got_http_message(ISrsHttpMessage* msg); virtual int on_got_http_message(ISrsHttpMessage* msg);
}; };

View file

@ -53,6 +53,7 @@ using namespace std;
#include <srs_app_source.hpp> #include <srs_app_source.hpp>
#include <srs_app_server.hpp> #include <srs_app_server.hpp>
#include <srs_app_statistic.hpp> #include <srs_app_statistic.hpp>
#include <srs_app_recv_thread.hpp>
SrsBufferCache::SrsBufferCache(SrsSource* s, SrsRequest* r) SrsBufferCache::SrsBufferCache(SrsSource* s, SrsRequest* r)
{ {
@ -538,10 +539,28 @@ int SrsLiveStream::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
SrsFastFlvStreamEncoder* ffe = dynamic_cast<SrsFastFlvStreamEncoder*>(enc); SrsFastFlvStreamEncoder* ffe = dynamic_cast<SrsFastFlvStreamEncoder*>(enc);
#endif #endif
// Use receive thread to accept the close event to avoid FD leak.
// @see https://github.com/ossrs/srs/issues/636#issuecomment-298208427
SrsHttpMessage* hr = dynamic_cast<SrsHttpMessage*>(r);
SrsResponseOnlyHttpConn* hc = dynamic_cast<SrsResponseOnlyHttpConn*>(hr->connection());
SrsHttpRecvThread* trd = new SrsHttpRecvThread(hc);
SrsAutoFree(SrsHttpRecvThread, trd);
if ((ret = trd->start()) != ERROR_SUCCESS) {
srs_error("http: start notify thread failed, ret=%d", ret);
return ret;
}
// TODO: free and erase the disabled entry after all related connections is closed. // TODO: free and erase the disabled entry after all related connections is closed.
while (entry->enabled) { while (entry->enabled) {
pprint->elapse(); pprint->elapse();
// Whether client closed the FD.
if ((ret = trd->error_code()) != ERROR_SUCCESS) {
return ret;
}
// get messages from consumer. // get messages from consumer.
// each msg in msgs.msgs must be free, for the SrsMessageArray never free them. // each msg in msgs.msgs must be free, for the SrsMessageArray never free them.
int count = 0; int count = 0;

View file

@ -31,6 +31,8 @@
#include <srs_core_performance.hpp> #include <srs_core_performance.hpp>
#include <srs_app_config.hpp> #include <srs_app_config.hpp>
#include <srs_app_source.hpp> #include <srs_app_source.hpp>
#include <srs_app_http_conn.hpp>
#include <srs_core_autofree.hpp>
using namespace std; using namespace std;
@ -527,3 +529,42 @@ void SrsPublishRecvThread::set_socket_buffer(int sleep_ms)
rtmp->set_recv_buffer(nb_rbuf); rtmp->set_recv_buffer(nb_rbuf);
} }
SrsHttpRecvThread::SrsHttpRecvThread(SrsResponseOnlyHttpConn* c)
{
conn = c;
error = ERROR_SUCCESS;
trd = new SrsOneCycleThread("http-receive", this);
}
SrsHttpRecvThread::~SrsHttpRecvThread()
{
srs_freep(trd);
}
int SrsHttpRecvThread::start()
{
return trd->start();
}
int SrsHttpRecvThread::error_code()
{
return error;
}
int SrsHttpRecvThread::cycle()
{
int ret = ERROR_SUCCESS;
while (true) {
ISrsHttpMessage* req = NULL;
SrsAutoFree(ISrsHttpMessage, req);
if ((ret = conn->pop_message(&req)) != ERROR_SUCCESS) {
error = ret;
break;
}
}
return ret;
}

View file

@ -39,6 +39,8 @@ class SrsRtmpConn;
class SrsSource; class SrsSource;
class SrsRequest; class SrsRequest;
class SrsConsumer; class SrsConsumer;
class SrsHttpConn;
class SrsResponseOnlyHttpConn;
/** /**
* The message consumer which consume a message. * The message consumer which consume a message.
@ -221,5 +223,29 @@ private:
virtual void set_socket_buffer(int sleep_ms); virtual void set_socket_buffer(int sleep_ms);
}; };
/**
* The HTTP receive thread, try to read messages util EOF.
* For example, the HTTP FLV serving thread will use the receive thread to break
* when client closed the request, to avoid FD leak.
* @see https://github.com/ossrs/srs/issues/636#issuecomment-298208427
*/
class SrsHttpRecvThread : public ISrsOneCycleThreadHandler
{
private:
SrsResponseOnlyHttpConn* conn;
SrsOneCycleThread* trd;
int error;
public:
SrsHttpRecvThread(SrsResponseOnlyHttpConn* c);
virtual ~SrsHttpRecvThread();
public:
virtual int start();
public:
virtual int error_code();
// interface ISrsOneCycleThreadHandler
public:
virtual int cycle();
};
#endif #endif

View file

@ -271,7 +271,7 @@ int SrsHttpFlvListener::listen(string i, int p)
return ret; return ret;
} }
srs_info("listen thread current_cid=%d, listen at port=%d, type=%d, fd=%d started success, ep=%s:%d", port, type, listener->fd(), ip.c_str(), port); srs_info("listen thread listen at port=%d, type=%d, fd=%d started success, ep=%s:%d", port, type, listener->fd(), ip.c_str(), port);
srs_trace("%s listen at tcp://%s:%d, fd=%d", srs_listener_type2string(type).c_str(), ip.c_str(), port, listener->fd()); srs_trace("%s listen at tcp://%s:%d, fd=%d", srs_listener_type2string(type).c_str(), ip.c_str(), port, listener->fd());