mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 03:31:05 +00:00
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:
parent
aaf9b46e2f
commit
16da96653a
1 changed files with 14 additions and 9 deletions
|
@ -11,11 +11,13 @@ struct _ThreadArgs {
|
||||||
gboolean is_simple;
|
gboolean is_simple;
|
||||||
GMutex nsapp_mutex;
|
GMutex nsapp_mutex;
|
||||||
GCond nsapp_cond;
|
GCond nsapp_cond;
|
||||||
|
gboolean nsapp_running;
|
||||||
};
|
};
|
||||||
|
|
||||||
@interface GstCocoaApplicationDelegate : NSObject <NSApplicationDelegate>
|
@interface GstCocoaApplicationDelegate : NSObject <NSApplicationDelegate>
|
||||||
@property (assign) GMutex *nsapp_mutex;
|
@property (assign) GMutex *nsapp_mutex;
|
||||||
@property (assign) GCond *nsapp_cond;
|
@property (assign) GCond *nsapp_cond;
|
||||||
|
@property (assign) gboolean *nsapp_running;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation GstCocoaApplicationDelegate
|
@implementation GstCocoaApplicationDelegate
|
||||||
|
@ -23,6 +25,7 @@ struct _ThreadArgs {
|
||||||
- (void)applicationDidFinishLaunching:(NSNotification *)notification
|
- (void)applicationDidFinishLaunching:(NSNotification *)notification
|
||||||
{
|
{
|
||||||
g_mutex_lock (self.nsapp_mutex);
|
g_mutex_lock (self.nsapp_mutex);
|
||||||
|
*self.nsapp_running = TRUE;
|
||||||
g_cond_signal (self.nsapp_cond);
|
g_cond_signal (self.nsapp_cond);
|
||||||
g_mutex_unlock (self.nsapp_mutex);
|
g_mutex_unlock (self.nsapp_mutex);
|
||||||
}
|
}
|
||||||
|
@ -35,7 +38,7 @@ gst_thread_func (ThreadArgs *args)
|
||||||
/* Only proceed once NSApp is running, otherwise we could
|
/* Only proceed once NSApp is running, otherwise we could
|
||||||
* attempt to call [NSApp: stop] before it's even started. */
|
* attempt to call [NSApp: stop] before it's even started. */
|
||||||
g_mutex_lock (&args->nsapp_mutex);
|
g_mutex_lock (&args->nsapp_mutex);
|
||||||
while (![[NSRunningApplication currentApplication] isFinishedLaunching]) {
|
while (!args->nsapp_running) {
|
||||||
g_cond_wait (&args->nsapp_cond, &args->nsapp_mutex);
|
g_cond_wait (&args->nsapp_cond, &args->nsapp_mutex);
|
||||||
}
|
}
|
||||||
g_mutex_unlock (&args->nsapp_mutex);
|
g_mutex_unlock (&args->nsapp_mutex);
|
||||||
|
@ -55,11 +58,11 @@ gst_thread_func (ThreadArgs *args)
|
||||||
windowNumber: 0
|
windowNumber: 0
|
||||||
context: nil
|
context: nil
|
||||||
subtype: NSEventSubtypeApplicationActivated
|
subtype: NSEventSubtypeApplicationActivated
|
||||||
data1: 0
|
data1: 0
|
||||||
data2: 0];
|
data2: 0];
|
||||||
|
|
||||||
[NSApp postEvent:event atStart:YES];
|
|
||||||
[NSApp stop:nil];
|
[NSApp stop:nil];
|
||||||
|
[NSApp postEvent:event atStart:YES];
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -73,11 +76,13 @@ run_main_with_nsapp (ThreadArgs args)
|
||||||
|
|
||||||
g_mutex_init (&args.nsapp_mutex);
|
g_mutex_init (&args.nsapp_mutex);
|
||||||
g_cond_init (&args.nsapp_cond);
|
g_cond_init (&args.nsapp_cond);
|
||||||
|
args.nsapp_running = FALSE;
|
||||||
|
|
||||||
[NSApplication sharedApplication];
|
[NSApplication sharedApplication];
|
||||||
delegate = [[GstCocoaApplicationDelegate alloc] init];
|
delegate = [[GstCocoaApplicationDelegate alloc] init];
|
||||||
delegate.nsapp_mutex = &args.nsapp_mutex;
|
delegate.nsapp_mutex = &args.nsapp_mutex;
|
||||||
delegate.nsapp_cond = &args.nsapp_cond;
|
delegate.nsapp_cond = &args.nsapp_cond;
|
||||||
|
delegate.nsapp_running = &args.nsapp_running;
|
||||||
[NSApp setDelegate:delegate];
|
[NSApp setDelegate:delegate];
|
||||||
|
|
||||||
/* This lets us show an icon in the dock and correctly focus opened windows */
|
/* 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
|
* @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
|
* @user_data: (nullable): user data to be passed to the main function
|
||||||
*
|
*
|
||||||
* Starts an NSApplication on the main thread before calling
|
* Starts an NSApplication on the main thread before calling
|
||||||
* the provided main() function on a secondary thread.
|
* the provided main() function on a secondary thread.
|
||||||
*
|
*
|
||||||
* This ensures that GStreamer can correctly perform actions
|
* This ensures that GStreamer can correctly perform actions
|
||||||
* such as creating a GL window, which require a Cocoa main loop
|
* such as creating a GL window, which require a Cocoa main loop
|
||||||
* to be running on the main thread.
|
* to be running on the main thread.
|
||||||
*
|
*
|
||||||
* Do not call this function more than once - especially while
|
* 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
|
* Since: 1.22
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
gst_macos_main_simple (GstMainFuncSimple main_func, gpointer user_data)
|
gst_macos_main_simple (GstMainFuncSimple main_func, gpointer user_data)
|
||||||
{
|
{
|
||||||
ThreadArgs args;
|
ThreadArgs args;
|
||||||
|
|
Loading…
Reference in a new issue