diff options
author | Alessandro Decina <alessandro.decina@collabora.co.uk> | 2012-05-26 12:21:18 +0200 |
---|---|---|
committer | Sebastian Dröge <sebastian.droege@collabora.co.uk> | 2012-05-31 10:26:10 +0200 |
commit | f20cdcd36b398d92dba5240dddb948cc49465180 (patch) | |
tree | 6dcbe09837675c94583d98abf18e7acdd359424e /sys | |
parent | 76b7998e4f424b8258049b6483b205784477d280 (diff) | |
download | gstreamer-plugins-good-f20cdcd36b398d92dba5240dddb948cc49465180.tar.gz |
osxvideosink: fix race in starting the runloop thread
Block gst_osx_video_sink_run_cocoa_loop until the loop thread has started and
finished initializing NSApp. Fixes occasional warnings/crashes due to two
threads going inside NSApp before finishLaunching had completed.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/osxvideo/osxvideosink.h | 4 | ||||
-rw-r--r-- | sys/osxvideo/osxvideosink.m | 40 |
2 files changed, 28 insertions, 16 deletions
diff --git a/sys/osxvideo/osxvideosink.h b/sys/osxvideo/osxvideosink.h index 2d18f137c..5d32f5ceb 100644 --- a/sys/osxvideo/osxvideosink.h +++ b/sys/osxvideo/osxvideosink.h @@ -77,10 +77,12 @@ struct _GstOSXVideoSink { NSView *superview; #ifdef RUN_NS_APP_THREAD NSThread *ns_app_thread; + GMutex *loop_thread_lock; + GCond *loop_thread_cond; #else guint cocoa_timeout; - gboolean app_started; #endif + gboolean app_started; gboolean keep_par; gboolean embed; }; diff --git a/sys/osxvideo/osxvideosink.m b/sys/osxvideo/osxvideosink.m index d4f33308e..a44422318 100644 --- a/sys/osxvideo/osxvideosink.m +++ b/sys/osxvideo/osxvideosink.m @@ -115,7 +115,7 @@ run_ns_app_loop (void) { } static void -gst_osx_video_sink_run_cocoa_loop (GstOSXVideoSink * osxvideosink ) +gst_osx_video_sink_run_cocoa_loop (GstOSXVideoSink * sink ) { /* Cocoa applications require a main runloop running to dispatch UI * events and process deferred calls to the main thread through @@ -138,14 +138,19 @@ gst_osx_video_sink_run_cocoa_loop (GstOSXVideoSink * osxvideosink ) method_exchangeImplementations(origIsMainThread, ourIsMainThread); - osxvideosink->ns_app_thread = [[NSThread alloc] - initWithTarget:osxvideosink->osxvideosinkobject + sink->ns_app_thread = [[NSThread alloc] + initWithTarget:sink->osxvideosinkobject selector:@selector(nsAppThread) object:nil]; - [osxvideosink->ns_app_thread start]; + [sink->ns_app_thread start]; + + g_mutex_lock (sink->loop_thread_lock); + while (!sink->app_started) + g_cond_wait (sink->loop_thread_cond, sink->loop_thread_lock); + g_mutex_unlock (sink->loop_thread_lock); #else /* assume that there is a GMainLoop and iterate the main runloop from there */ - osxvideosink->cocoa_timeout = g_timeout_add (10, + sink->cocoa_timeout = g_timeout_add (10, (GSourceFunc) run_ns_app_loop, NULL); #endif } @@ -356,9 +361,7 @@ gst_osx_video_sink_change_state (GstElement * element, case GST_STATE_CHANGE_PAUSED_TO_READY: GST_VIDEO_SINK_WIDTH (osxvideosink) = 0; GST_VIDEO_SINK_HEIGHT (osxvideosink) = 0; -#ifndef RUN_NS_APP_THREAD osxvideosink->app_started = FALSE; -#endif gst_osx_video_sink_osxwindow_destroy (osxvideosink); break; case GST_STATE_CHANGE_READY_TO_NULL: @@ -450,16 +453,17 @@ gst_osx_video_sink_get_property (GObject * object, guint prop_id, static void -gst_osx_video_sink_init (GstOSXVideoSink * osxvideosink) +gst_osx_video_sink_init (GstOSXVideoSink * sink) { - osxvideosink->osxwindow = NULL; - osxvideosink->superview = NULL; - osxvideosink->osxvideosinkobject = [[GstOSXVideoSinkObject alloc] - initWithSink:osxvideosink]; -#ifndef RUN_NS_APP_THREAD - osxvideosink->app_started = FALSE; + sink->osxwindow = NULL; + sink->superview = NULL; + sink->osxvideosinkobject = [[GstOSXVideoSinkObject alloc] initWithSink:sink]; +#ifdef RUN_NS_APP_THREAD + sink->loop_thread_lock = g_mutex_new (); + sink->loop_thread_cond = g_cond_new (); #endif - osxvideosink->keep_par = FALSE; + sink->app_started = FALSE; + sink->keep_par = FALSE; } static void @@ -857,6 +861,7 @@ gst_osx_video_sink_get_type (void) -(void) nsAppThread { NSAutoreleasePool *pool; + GstOSXVideoSink *sink = osxvideosink; /* set the main runloop as the runloop for the current thread. This has the * effect that calling NSApp nextEventMatchingMask:untilDate:inMode:dequeue @@ -874,6 +879,11 @@ gst_osx_video_sink_get_type (void) [NSApplication sharedApplication]; [NSApp finishLaunching]; + g_mutex_lock (sink->loop_thread_lock); + sink->app_started = TRUE; + g_cond_signal (sink->loop_thread_cond); + g_mutex_unlock (sink->loop_thread_lock); + /* run the loop */ run_ns_app_loop (); |