From a26c37021dbcad52a04a570bdd6ac583e314a912 Mon Sep 17 00:00:00 2001 From: WarmUpTill <19472752+WarmUpTill@users.noreply.github.com> Date: Sat, 5 Jul 2025 18:22:45 +0200 Subject: [PATCH] Fix crash on OBS shutdown --- lib/switcher-data.cpp | 8 ++++++++ lib/switcher-data.hpp | 8 ++++---- lib/utils/websocket-api.cpp | 18 +++++++++++++++++- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/lib/switcher-data.cpp b/lib/switcher-data.cpp index bfc6fade..07d634c4 100644 --- a/lib/switcher-data.cpp +++ b/lib/switcher-data.cpp @@ -25,6 +25,14 @@ SwitcherData::SwitcherData(obs_module_t *m, translateFunc t) _translate = t; } +SwitcherData::~SwitcherData() +{ + // Assume that OBS is shutting down, as the switcher object will only be + // destroyed when the plugin is unloaded + obsIsShuttingDown = true; + Stop(); +} + const char *SwitcherData::Translate(const char *text) { return _translate(text); diff --git a/lib/switcher-data.hpp b/lib/switcher-data.hpp index 333c2a28..79f0dac4 100644 --- a/lib/switcher-data.hpp +++ b/lib/switcher-data.hpp @@ -45,6 +45,9 @@ std::unique_lock *GetSwitcherLoopLock(); class SwitcherData { public: + SwitcherData(obs_module_t *modulePtr, translateFunc translate); + ~SwitcherData(); + void Thread(); void Start(); void Stop(); @@ -85,9 +88,6 @@ public: /* --- End of saving / loading section --- */ - SwitcherData(obs_module_t *m, translateFunc t); - inline ~SwitcherData() { Stop(); } - public: SwitcherThread *th = nullptr; std::mutex m; @@ -102,7 +102,7 @@ public: bool firstBoot = true; bool transitionActive = false; bool sceneColletionStop = false; - bool obsIsShuttingDown = false; + std::atomic_bool obsIsShuttingDown = {false}; bool firstInterval = true; bool firstIntervalAfterStop = true; bool startupLoadDone = false; diff --git a/lib/utils/websocket-api.cpp b/lib/utils/websocket-api.cpp index 3d06813a..dcc9b302 100644 --- a/lib/utils/websocket-api.cpp +++ b/lib/utils/websocket-api.cpp @@ -117,9 +117,25 @@ void RegisterWebsocketRequest( }); } +static bool websocketModuleIsLoaded() +{ + bool websocketModuleFound = false; + const auto checkModule = [](void *param, obs_module_t *module) { + bool *moduleFound = static_cast(param); + auto name = obs_get_module_name(module); + if (name && strcmp(name, "obs-websocket") == 0) { + *moduleFound = true; + } + }; + obs_enum_modules(checkModule, &websocketModuleFound); + return websocketModuleFound; +} + void SendWebsocketVendorEvent(const std::string &eventName, obs_data_t *data) { - if (OBSIsShuttingDown()) { + // If obs-websocket was loaded, but was unloaded at some point any calls + // to obs_websocket_vendor_emit_event() will segfault + if (OBSIsShuttingDown() || !websocketModuleIsLoaded()) { return; } obs_websocket_vendor_emit_event(vendor, eventName.c_str(), data);