mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
fix memory leak at source. 2.0.214
This commit is contained in:
parent
6ec60b0a21
commit
c7b97aa1c3
8 changed files with 103 additions and 4 deletions
|
@ -58,6 +58,9 @@ using namespace std;
|
|||
// when got these videos or audios, pure audio or video, mix ok.
|
||||
#define SRS_MIX_CORRECT_PURE_AV 10
|
||||
|
||||
// the time to cleanup source in ms.
|
||||
#define SRS_SOURCE_CLEANUP 30000
|
||||
|
||||
int _srs_time_jitter_string2int(std::string time_jitter)
|
||||
{
|
||||
if (time_jitter == "full") {
|
||||
|
@ -796,16 +799,39 @@ void SrsSource::dispose_all()
|
|||
}
|
||||
|
||||
int SrsSource::cycle_all()
|
||||
{
|
||||
int cid = _srs_context->get_id();
|
||||
int ret = do_cycle_all();
|
||||
_srs_context->set_id(cid);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SrsSource::do_cycle_all()
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
// TODO: FIXME: support remove dead source for a long time.
|
||||
std::map<std::string, SrsSource*>::iterator it;
|
||||
for (it = pool.begin(); it != pool.end(); ++it) {
|
||||
for (it = pool.begin(); it != pool.end();) {
|
||||
SrsSource* source = it->second;
|
||||
if ((ret = source->cycle()) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (source->expired()) {
|
||||
int cid = source->source_id();
|
||||
if (cid == -1 && source->pre_source_id() > 0) {
|
||||
cid = source->pre_source_id();
|
||||
}
|
||||
if (cid > 0) {
|
||||
_srs_context->set_id(cid);
|
||||
}
|
||||
srs_trace("cleanup die source, total=%d", (int)pool.size());
|
||||
|
||||
srs_freep(source);
|
||||
pool.erase(it++);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -916,7 +942,8 @@ SrsSource::SrsSource()
|
|||
cache_metadata = cache_sh_video = cache_sh_audio = NULL;
|
||||
|
||||
_can_publish = true;
|
||||
_source_id = -1;
|
||||
_pre_source_id = _source_id = -1;
|
||||
die_at = -1;
|
||||
|
||||
play_edge = new SrsPlayEdge();
|
||||
publish_edge = new SrsPublishEdge();
|
||||
|
@ -1001,6 +1028,20 @@ int SrsSource::cycle()
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool SrsSource::expired()
|
||||
{
|
||||
if (!consumers.empty() || die_at == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int64_t now = srs_get_system_time_ms();
|
||||
if (now > die_at + SRS_SOURCE_CLEANUP) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int SrsSource::initialize(SrsRequest* r, ISrsSourceHandler* h, ISrsHlsHandler* hh)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
@ -1355,6 +1396,12 @@ int SrsSource::on_source_id_changed(int id)
|
|||
return ret;
|
||||
}
|
||||
|
||||
if (_pre_source_id == -1) {
|
||||
_pre_source_id = id;
|
||||
} else if (_pre_source_id != _source_id) {
|
||||
_pre_source_id = _source_id;
|
||||
}
|
||||
|
||||
_source_id = id;
|
||||
|
||||
// notice all consumer
|
||||
|
@ -1372,6 +1419,11 @@ int SrsSource::source_id()
|
|||
return _source_id;
|
||||
}
|
||||
|
||||
int SrsSource::pre_source_id()
|
||||
{
|
||||
return _pre_source_id;
|
||||
}
|
||||
|
||||
bool SrsSource::can_publish(bool is_edge)
|
||||
{
|
||||
if (is_edge) {
|
||||
|
@ -2107,6 +2159,11 @@ int SrsSource::on_publish()
|
|||
|
||||
void SrsSource::on_unpublish()
|
||||
{
|
||||
// ignore when already unpublished.
|
||||
if (_can_publish) {
|
||||
return;
|
||||
}
|
||||
|
||||
// destroy all forwarders
|
||||
destroy_forwarders();
|
||||
|
||||
|
@ -2142,12 +2199,18 @@ void SrsSource::on_unpublish()
|
|||
SrsStatistic* stat = SrsStatistic::instance();
|
||||
stat->on_stream_close(_req);
|
||||
handler->on_unpublish(this, _req);
|
||||
|
||||
// no consumer, stream is die.
|
||||
if (consumers.empty()) {
|
||||
die_at = srs_get_system_time_ms();
|
||||
}
|
||||
}
|
||||
|
||||
int SrsSource::create_consumer(SrsConnection* conn, SrsConsumer*& consumer, bool ds, bool dm, bool dg)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
die_at = -1;
|
||||
consumer = new SrsConsumer(this, conn);
|
||||
consumers.push_back(consumer);
|
||||
|
||||
|
@ -2224,6 +2287,7 @@ void SrsSource::on_consumer_destroy(SrsConsumer* consumer)
|
|||
|
||||
if (consumers.empty()) {
|
||||
play_edge->on_all_client_stop();
|
||||
die_at = srs_get_system_time_ms();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue