diff --git a/README.md b/README.md index 9a162dc76e..46631a4604 100755 --- a/README.md +++ b/README.md @@ -344,6 +344,7 @@ Remark: ## History +* v2.0, 2016-12-13, fix #713, refine source to avoid critical fetch and create. 2.0.222 * v2.0, 2016-11-09, [2.0 beta2(2.0.221)][r2.0b2] released. 86691 lines. * v2.0, 2016-11-05, fix #654, crash when source cleanup for edge. 2.0.221 * v2.0, 2016-10-26, fix #666, crash when source cleanup for http-flv. 2.0.220 diff --git a/trunk/src/app/srs_app_http_stream.cpp b/trunk/src/app/srs_app_http_stream.cpp index 0cd864a970..7d193ed4e5 100755 --- a/trunk/src/app/srs_app_http_stream.cpp +++ b/trunk/src/app/srs_app_http_stream.cpp @@ -1228,11 +1228,9 @@ int SrsHttpStreamServer::hijack(ISrsHttpMessage* request, ISrsHttpHandler** ph) } } - SrsSource* s = SrsSource::fetch(r); - if (!s) { - if ((ret = SrsSource::create(r, server, server, &s)) != ERROR_SUCCESS) { - return ret; - } + SrsSource* s = NULL; + if ((ret = SrsSource::fetch_or_create(r, server, server, &s)) != ERROR_SUCCESS) { + return ret; } srs_assert(s != NULL); diff --git a/trunk/src/app/srs_app_rtmp_conn.cpp b/trunk/src/app/srs_app_rtmp_conn.cpp index 0e26fb0075..b097837898 100755 --- a/trunk/src/app/srs_app_rtmp_conn.cpp +++ b/trunk/src/app/srs_app_rtmp_conn.cpp @@ -486,11 +486,9 @@ int SrsRtmpConn::stream_service_cycle() rtmp->set_send_timeout(SRS_CONSTS_RTMP_SEND_TIMEOUT_US); // find a source to serve. - SrsSource* source = SrsSource::fetch(req); - if (!source) { - if ((ret = SrsSource::create(req, server, server, &source)) != ERROR_SUCCESS) { - return ret; - } + SrsSource* source = NULL; + if ((ret = SrsSource::fetch_or_create(req, server, server, &source)) != ERROR_SUCCESS) { + return ret; } srs_assert(source != NULL); diff --git a/trunk/src/app/srs_app_source.cpp b/trunk/src/app/srs_app_source.cpp index 0f2f18404f..a76cd839e9 100755 --- a/trunk/src/app/srs_app_source.cpp +++ b/trunk/src/app/srs_app_source.cpp @@ -731,17 +731,23 @@ ISrsSourceHandler::~ISrsSourceHandler() std::map SrsSource::pool; -int SrsSource::create(SrsRequest* r, ISrsSourceHandler* h, ISrsHlsHandler* hh, SrsSource** pps) +int SrsSource::fetch_or_create(SrsRequest* r, ISrsSourceHandler* h, ISrsHlsHandler* hh, SrsSource** pps) { int ret = ERROR_SUCCESS; + SrsSource* source = NULL; + if ((source = fetch(r)) != NULL) { + *pps = source; + return ret; + } + string stream_url = r->get_stream_url(); string vhost = r->vhost; // should always not exists for create a source. srs_assert (pool.find(stream_url) == pool.end()); - SrsSource* source = new SrsSource(); + source = new SrsSource(); if ((ret = source->initialize(r, h, hh)) != ERROR_SUCCESS) { srs_freep(source); return ret; @@ -774,20 +780,6 @@ SrsSource* SrsSource::fetch(SrsRequest* r) return source; } -SrsSource* SrsSource::fetch(std::string vhost, std::string app, std::string stream) -{ - SrsSource* source = NULL; - string stream_url = srs_generate_stream_url(vhost, app, stream); - - if (pool.find(stream_url) == pool.end()) { - return NULL; - } - - source = pool[stream_url]; - - return source; -} - void SrsSource::dispose_all() { std::map::iterator it; diff --git a/trunk/src/app/srs_app_source.hpp b/trunk/src/app/srs_app_source.hpp index 616e739040..e773a31f81 100755 --- a/trunk/src/app/srs_app_source.hpp +++ b/trunk/src/app/srs_app_source.hpp @@ -418,22 +418,20 @@ class SrsSource : public ISrsReloadHandler static std::map pool; public: /** - * find stream by vhost/app/stream. + * create source when fetch from cache failed. * @param r the client request. * @param h the event handler for source. * @param hh the event handler for hls. * @param pps the matched source, if success never be NULL. */ - static int create(SrsRequest* r, ISrsSourceHandler* h, ISrsHlsHandler* hh, SrsSource** pps); + static int fetch_or_create(SrsRequest* r, ISrsSourceHandler* h, ISrsHlsHandler* hh, SrsSource** pps); +private: /** * get the exists source, NULL when not exists. * update the request and return the exists source. */ static SrsSource* fetch(SrsRequest* r); - /** - * get the exists source by stream info(vhost, app, stream), NULL when not exists. - */ - static SrsSource* fetch(std::string vhost, std::string app, std::string stream); +public: /** * dispose and cycle all sources. */