From 16da96653ad943e7b4ca92ee013fb112b57098ce Mon Sep 17 00:00:00 2001 From: Corentin Damman Date: Tue, 1 Oct 2024 12:26:40 +0000 Subject: [PATCH] macos: Fix race conditions This commit fixes two issues: - The event must be posted *after* calling stop, otherwise a race condition can occur and the app never stops - isFinishedLaunching and applicationDidFinishLaunching are not always synchronized, causing sometimes a deadlock on the g_cond_wait never catching the g_cond_signal Part-of: --- subprojects/gstreamer/gst/gstmacos.m | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/subprojects/gstreamer/gst/gstmacos.m b/subprojects/gstreamer/gst/gstmacos.m index dbdb1a70a3..bb943ac825 100644 --- a/subprojects/gstreamer/gst/gstmacos.m +++ b/subprojects/gstreamer/gst/gstmacos.m @@ -11,11 +11,13 @@ struct _ThreadArgs { gboolean is_simple; GMutex nsapp_mutex; GCond nsapp_cond; + gboolean nsapp_running; }; @interface GstCocoaApplicationDelegate : NSObject @property (assign) GMutex *nsapp_mutex; @property (assign) GCond *nsapp_cond; +@property (assign) gboolean *nsapp_running; @end @implementation GstCocoaApplicationDelegate @@ -23,6 +25,7 @@ struct _ThreadArgs { - (void)applicationDidFinishLaunching:(NSNotification *)notification { g_mutex_lock (self.nsapp_mutex); + *self.nsapp_running = TRUE; g_cond_signal (self.nsapp_cond); g_mutex_unlock (self.nsapp_mutex); } @@ -35,7 +38,7 @@ gst_thread_func (ThreadArgs *args) /* Only proceed once NSApp is running, otherwise we could * attempt to call [NSApp: stop] before it's even started. */ g_mutex_lock (&args->nsapp_mutex); - while (![[NSRunningApplication currentApplication] isFinishedLaunching]) { + while (!args->nsapp_running) { g_cond_wait (&args->nsapp_cond, &args->nsapp_mutex); } g_mutex_unlock (&args->nsapp_mutex); @@ -55,11 +58,11 @@ gst_thread_func (ThreadArgs *args) windowNumber: 0 context: nil subtype: NSEventSubtypeApplicationActivated - data1: 0 + data1: 0 data2: 0]; - [NSApp postEvent:event atStart:YES]; [NSApp stop:nil]; + [NSApp postEvent:event atStart:YES]; return ret; } @@ -73,11 +76,13 @@ run_main_with_nsapp (ThreadArgs args) g_mutex_init (&args.nsapp_mutex); g_cond_init (&args.nsapp_cond); + args.nsapp_running = FALSE; [NSApplication sharedApplication]; delegate = [[GstCocoaApplicationDelegate alloc] init]; delegate.nsapp_mutex = &args.nsapp_mutex; delegate.nsapp_cond = &args.nsapp_cond; + delegate.nsapp_running = &args.nsapp_running; [NSApp setDelegate:delegate]; /* This lets us show an icon in the dock and correctly focus opened windows */ @@ -102,11 +107,11 @@ run_main_with_nsapp (ThreadArgs args) * @argv: (array length=argc): an array of arguments to be passed to the main function * @user_data: (nullable): user data to be passed to the main function * - * Starts an NSApplication on the main thread before calling - * the provided main() function on a secondary thread. - * - * This ensures that GStreamer can correctly perform actions - * such as creating a GL window, which require a Cocoa main loop + * Starts an NSApplication on the main thread before calling + * the provided main() function on a secondary thread. + * + * This ensures that GStreamer can correctly perform actions + * such as creating a GL window, which require a Cocoa main loop * to be running on the main thread. * * Do not call this function more than once - especially while @@ -144,7 +149,7 @@ gst_macos_main (GstMainFunc main_func, int argc, char **argv, gpointer user_data * * Since: 1.22 */ -int +int gst_macos_main_simple (GstMainFuncSimple main_func, gpointer user_data) { ThreadArgs args;