avmedia/source/gstreamer/gstplayer.cxx | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-)
New commits: commit 04311ac7bf89b2496a951b377c8d7f6be5b8c188 Author: Stephan Bergmann <[email protected]> AuthorDate: Thu Nov 27 10:17:18 2025 +0100 Commit: Stephan Bergmann <[email protected]> CommitDate: Thu Nov 27 13:57:07 2025 +0100 Fix race between MissingPluginInstallerThread launch() and join() CppunitTest_slideshow_engine occasionally failed at least on <https://ci.libreoffice.org/job/gerrit_linux_gcc_release/>, with a MissingPluginInstallerThread still executing during exit. What happened was that the join() in MissingPluginInstaller::detach was executed before the launch() in the MissingPluginInstaller launchUi link was called. So that call to join() did nothing (cf. the documentation of osl_joinWithThread in include/osl/thread.h: "Returns immediately if Thread is NULL.") and then the call to create() started executing the thread during exit. Change-Id: I5141eba64e6631cbf41026af4bbee4fc0a285a4f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/194686 Reviewed-by: Noel Grandin <[email protected]> Tested-by: Jenkins Reviewed-by: Stephan Bergmann <[email protected]> Code-Style: Stephan Bergmann <[email protected]> diff --git a/avmedia/source/gstreamer/gstplayer.cxx b/avmedia/source/gstreamer/gstplayer.cxx index 602435db5f83..d63b8e809bf7 100644 --- a/avmedia/source/gstreamer/gstplayer.cxx +++ b/avmedia/source/gstreamer/gstplayer.cxx @@ -70,8 +70,29 @@ class MissingPluginInstallerThread: public salhelper::Thread { public: MissingPluginInstallerThread(): Thread("MissingPluginInstaller") {} + void launchIfNotJoined() { + std::scoped_lock g(mutex_); + if (!joined_) { + launch(); + } + } + + void joinIfCreated() { + { + std::scoped_lock g(mutex_); + joined_ = true; + } + join(); // if not yet created, join() does nothing + } + private: + using salhelper::Thread::launch; + using salhelper::Thread::join; + void execute() override; + + std::mutex mutex_; + bool joined_ = false; }; @@ -156,7 +177,7 @@ void MissingPluginInstaller::report( launch = currentThread_; } if (join.is()) { - join->join(); + join->joinIfCreated(); } launch->acquire(); Application::PostUserEvent( @@ -209,7 +230,7 @@ void MissingPluginInstaller::detach(Player const * source) { } if (join.is()) { // missing cancellability of gst_install_plugins_sync - join->join(); + join->joinIfCreated(); } } @@ -238,7 +259,7 @@ IMPL_STATIC_LINK(MissingPluginInstaller, launchUi, void *, p, void) // loop), and hopefully fine to call gst_is_missing_plugin_message and // gst_missing_plugin_message_get_installer_detail before calling // gst_pb_utils_init - ref->launch(); + ref->launchIfNotJoined(); }
