From 957140db510be0620f304c6828be64be65cd92ec Mon Sep 17 00:00:00 2001 From: Bahamut Date: Thu, 15 Aug 2024 10:41:57 +0800 Subject: [PATCH] Live: Crash for invalid live stream state when unmount HTTP. v6.0.146 (#4141) When unpublishing, the handler callback that will stop the coroutine: ```cpp _can_publish = true; handler->on_unpublish(req); ``` In this handler, the `http_unmount` will be called: ```cpp void SrsHttpStreamServer::http_unmount(SrsRequest* r) cache->stop(); ``` In this `http_unmount` function, there could be context switching. In such a situation, a new connection might publish the stream while the unpublish process is freeing the stream, leading to a crash. To prevent a new publisher, we should change the state only after all handlers and hooks are completed. --------- Co-authored-by: liumengte Co-authored-by: winlin --- trunk/doc/CHANGELOG.md | 1 + trunk/src/app/srs_app_source.cpp | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/trunk/doc/CHANGELOG.md b/trunk/doc/CHANGELOG.md index 92151bbfe..6225a1e4d 100644 --- a/trunk/doc/CHANGELOG.md +++ b/trunk/doc/CHANGELOG.md @@ -7,6 +7,7 @@ The changelog for SRS. ## SRS 6.0 Changelog +* v6.0, 2024-08-14, Merge [#4141](https://github.com/ossrs/srs/pull/4141): Live: Crash for invalid live stream state when unmount HTTP. v6.0.146 (#4141) * v6.0, 2024-08-13, Merge [#4092](https://github.com/ossrs/srs/pull/4092): Config: Improve env config to support multi values. v6.0.146 (#4092) * v6.0, 2024-07-27, Merge [#4127](https://github.com/ossrs/srs/pull/4127): Transcode: Support video codec such as h264_qsv and libx265. v6.0.145 (#4127) * v6.0, 2024-07-27, Merge [#4101](https://github.com/ossrs/srs/pull/4101): GB28181: Support external SIP server. v6.0.144 (#4101) diff --git a/trunk/src/app/srs_app_source.cpp b/trunk/src/app/srs_app_source.cpp index 2a9c59a58..bdbfc829e 100755 --- a/trunk/src/app/srs_app_source.cpp +++ b/trunk/src/app/srs_app_source.cpp @@ -2632,8 +2632,7 @@ void SrsLiveSource::on_unpublish() meta->update_previous_ash(); srs_trace("cleanup when unpublish"); - - _can_publish = true; + if (!_source_id.empty()) { _pre_source_id = _source_id; } @@ -2655,6 +2654,8 @@ void SrsLiveSource::on_unpublish() if (consumers.empty()) { stream_die_at_ = srs_get_system_time(); } + + _can_publish = true; } srs_error_t SrsLiveSource::create_consumer(SrsLiveConsumer*& consumer)