diff --git a/NEWS b/NEWS index 036a6e3563..dbe27b8e09 100644 --- a/NEWS +++ b/NEWS @@ -34,6 +34,8 @@ ver 0.25 (not yet released) ver 0.24.15 (not yet released) * protocol - fix crash on "sticker delete" +* input + - alsa, curl, nfs: fix stalled transfers * playlist - asx, pls, rss, xspf: limit to 16 MB - cue: fix problem playing CUE tracks in music directory root diff --git a/src/input/AsyncInputStream.cxx b/src/input/AsyncInputStream.cxx index 0701d6f4ea..1eae5f6230 100644 --- a/src/input/AsyncInputStream.cxx +++ b/src/input/AsyncInputStream.cxx @@ -141,7 +141,6 @@ AsyncInputStream::SeekDone() noexcept open = true; seek_state = SeekState::NONE; - caller_cond.notify_one(); InvokeOnAvailable(); } @@ -207,10 +206,8 @@ AsyncInputStream::CommitWriteBuffer(size_t nbytes) noexcept if (!IsReady()) SetReady(); - else { - caller_cond.notify_one(); + else InvokeOnAvailable(); - } } void @@ -240,10 +237,8 @@ AsyncInputStream::AppendToBuffer(std::span src) noexcept if (!IsReady()) SetReady(); - else { - caller_cond.notify_one(); + else InvokeOnAvailable(); - } } void @@ -254,7 +249,6 @@ AsyncInputStream::DeferredResume() noexcept if (postponed_exception) [[unlikely]] { /* do not proceed, first the caller must handle the pending error */ - caller_cond.notify_one(); InvokeOnAvailable(); return; } @@ -263,7 +257,6 @@ AsyncInputStream::DeferredResume() noexcept Resume(); } catch (...) { postponed_exception = std::current_exception(); - caller_cond.notify_one(); InvokeOnAvailable(); } } @@ -279,7 +272,6 @@ AsyncInputStream::DeferredSeek() noexcept /* do not proceed, first the caller must handle the pending error */ seek_state = SeekState::NONE; - caller_cond.notify_one(); InvokeOnAvailable(); return; } @@ -295,7 +287,6 @@ AsyncInputStream::DeferredSeek() noexcept } catch (...) { seek_state = SeekState::NONE; postponed_exception = std::current_exception(); - caller_cond.notify_one(); InvokeOnAvailable(); } } diff --git a/src/input/AsyncInputStream.hxx b/src/input/AsyncInputStream.hxx index be93405709..ac54f91350 100644 --- a/src/input/AsyncInputStream.hxx +++ b/src/input/AsyncInputStream.hxx @@ -56,6 +56,14 @@ class AsyncInputStream : public InputStream { protected: std::exception_ptr postponed_exception; + /** + * Notify both the synchronous caller and the InputStream handler. + */ + void InvokeOnAvailable() noexcept { + caller_cond.notify_one(); + InputStream::InvokeOnAvailable(); + } + public: AsyncInputStream(EventLoop &event_loop, std::string_view _url, Mutex &_mutex, diff --git a/src/input/plugins/AlsaInputPlugin.cxx b/src/input/plugins/AlsaInputPlugin.cxx index 5fc8dd99af..19534135f3 100644 --- a/src/input/plugins/AlsaInputPlugin.cxx +++ b/src/input/plugins/AlsaInputPlugin.cxx @@ -244,6 +244,7 @@ try { CommitWriteBuffer(nbytes); } catch (...) { + const std::lock_guard protect{mutex}; postponed_exception = std::current_exception(); InvokeOnAvailable(); } diff --git a/src/playlist/Length.cxx b/src/playlist/Length.cxx index 1042cd7337..0580a31a26 100644 --- a/src/playlist/Length.cxx +++ b/src/playlist/Length.cxx @@ -28,7 +28,7 @@ static void playlist_provider_length(Response &r, const SongLoader &loader, const std::string_view uri, - SongEnumerator &e) noexcept + SongEnumerator &e) { const auto base_uri = PathTraitsUTF8::GetParent(uri); diff --git a/src/playlist/Print.cxx b/src/playlist/Print.cxx index 278154f424..3a44a2f732 100644 --- a/src/playlist/Print.cxx +++ b/src/playlist/Print.cxx @@ -27,7 +27,7 @@ playlist_provider_print(Response &r, SongEnumerator &e, unsigned start_index, unsigned end_index, - bool detail) noexcept + bool detail) { const auto base_uri = PathTraitsUTF8::GetParent(uri); @@ -59,7 +59,7 @@ playlist_provider_search_print(Response &r, SongEnumerator &e, unsigned start_index, unsigned end_index, - SongFilter *filter) noexcept + SongFilter *filter) { const auto base_uri = PathTraitsUTF8::GetParent(uri);