@@ -34,7 +34,9 @@ with this program. If not, see <https://www.gnu.org/licenses/>
3434#include " video/filter-video-capture.hpp"
3535#include " plugin-support.h"
3636#include " plugin-main.hpp"
37+ #ifdef ENABLE_OBS_WEBSOCKET
3738#include " plugin-websocket.hpp"
39+ #endif
3840#include " utils.hpp"
3941
4042#define SETTINGS_JSON_NAME " recently.json"
@@ -146,9 +148,12 @@ BranchOutputFilter::BranchOutputFilter(obs_data_t *settings, obs_source_t *sourc
146148 // FIXME: libobs has no proc_handler_remove(). If it gains one, pair
147149 // unregistration with ~BranchOutputFilter().
148150 proc_handler_t *ph = obs_source_get_proc_handler (filterSource);
149- auto replayBufferProcDecl =
151+ // static: proc_handler_add() does not document whether it copies the decl string,
152+ // so the buffer must outlive every registered handler.
153+ static const std::string replayBufferProcDecl =
150154 std::string (" void " ) + PROC_OVERRIDE_REPLAY_BUFFER_FILENAME_FORMAT + " (in string format)" ;
151- auto recordingProcDecl = std::string (" void " ) + PROC_OVERRIDE_RECORDING_FILENAME_FORMAT + " (in string format)" ;
155+ static const std::string recordingProcDecl =
156+ std::string (" void " ) + PROC_OVERRIDE_RECORDING_FILENAME_FORMAT + " (in string format)" ;
152157 proc_handler_add (ph, replayBufferProcDecl.c_str (), onOverrideReplayBufferFilenameFormat, this );
153158 proc_handler_add (ph, recordingProcDecl.c_str (), onOverrideRecordingFilenameFormat, this );
154159
@@ -1929,26 +1934,27 @@ void obs_module_post_load()
19291934 proc_handler_t *ph = obs_get_proc_handler ();
19301935 proc_handler_add (ph, " void osi_branch_output_get_filter_list(out string json)" , onGetFilterList, nullptr );
19311936
1937+ #ifdef ENABLE_OBS_WEBSOCKET
19321938 registerWebSocketVendorRequests ();
1939+ #endif
19331940}
19341941
19351942void obs_module_unload ()
19361943{
1937- // Publish nullptr before unregistering vendor requests so that any
1938- // vendor callback already in flight observes a null dock and bails out
1939- // of the UI dispatch path. Doing this first shrinks (but does not
1940- // close) the worker race window.
1944+ // Stop accepting new vendor dispatches before tearing down the dock so
1945+ // a worker cannot start a fresh UI invocation against a destroyed dock.
19411946 //
1942- // FIXME: narrow worker race remains. Proper fixes are an in-flight
1943- // counter (wait for zero before remove_dock) or QPointer + deleteLater
1944- // + processEvents drain. Current code accepts the race because the
1945- // worst observable effect is a silent empty result.
1947+ // FIXME: narrow worker race remains for a callback that already loaded
1948+ // a non-null dock pointer. Proper fixes are an in-flight counter or
1949+ // QPointer + deleteLater + processEvents drain.
1950+ #ifdef ENABLE_OBS_WEBSOCKET
1951+ unregisterWebSocketVendorRequests ();
1952+ #endif
1953+
19461954 if (statusDock.exchange (nullptr ) != nullptr ) {
19471955 obs_frontend_remove_dock (" BranchOutputStatusDock" );
19481956 }
19491957
1950- unregisterWebSocketVendorRequests ();
1951-
19521958 pthread_mutex_destroy (&pluginMutex);
19531959
19541960 obs_log (LOG_INFO , " Plugin unloaded" );
0 commit comments