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: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7593>
This commit is contained in:
Corentin Damman 2024-10-01 12:26:40 +00:00
parent aaf9b46e2f
commit 16da96653a

View file

@ -11,11 +11,13 @@ struct _ThreadArgs {
gboolean is_simple;
GMutex nsapp_mutex;
GCond nsapp_cond;
gboolean nsapp_running;
};
@interface GstCocoaApplicationDelegate : NSObject <NSApplicationDelegate>
@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);
@ -58,8 +61,8 @@ gst_thread_func (ThreadArgs *args)
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 */