[vlc-commits] macosx: use a dispatch queue to notify extensions about modified inputs

David Fuhrmann git at videolan.org
Mon Apr 28 11:47:39 CEST 2014


vlc | branch: master | David Fuhrmann <dfuhrmann at videolan.org> | Fri Apr 25 15:22:41 2014 +0200| [46d154e195544f2312b51593449ac6c9a903b932] | committer: David Fuhrmann

macosx: use a dispatch queue to notify extensions about modified inputs

This notifies the extension manager on the non-main thread as before,
the queue ensures that changes in quick succession are processed in-order.
For the rationale see a8ff52782d21b6425d8c26c96a2269939ac6ce18.

Fixes another deadlock on application termination.

close #10647

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=46d154e195544f2312b51593449ac6c9a903b932
---

 modules/gui/macosx/intf.h |    5 +++--
 modules/gui/macosx/intf.m |   32 +++++++++++++++-----------------
 2 files changed, 18 insertions(+), 19 deletions(-)

diff --git a/modules/gui/macosx/intf.h b/modules/gui/macosx/intf.h
index 5f74059..91c8fdb 100644
--- a/modules/gui/macosx/intf.h
+++ b/modules/gui/macosx/intf.h
@@ -68,7 +68,7 @@ audio_output_t *getAout(void);
 @interface VLCMain : NSObject <NSWindowDelegate, NSApplicationDelegate>
 {
     intf_thread_t *p_intf;      /* The main intf object */
-    input_thread_t *p_current_input, *p_input_changed;
+    input_thread_t *p_current_input;
     BOOL launched;              /* finishedLaunching */
     int items_at_launch;        /* items in playlist after launch */
     id o_mainmenu;              /* VLCMainMenu */
@@ -119,6 +119,8 @@ audio_output_t *getAout(void);
     NSTimer *o_itunes_play_timer;
 
     BOOL b_playlist_updated_selector_in_queue;
+
+    dispatch_queue_t informInputChangedQueue;
 }
 
 @property (readonly) VLCVoutWindowController* voutController;
@@ -149,7 +151,6 @@ audio_output_t *getAout(void);
 - (BOOL)hasDefinedShortcutKey:(NSEvent *)o_event force:(BOOL)b_force;
 
 - (void)PlaylistItemChanged;
-- (void)informInputChanged;
 - (void)playbackStatusUpdated;
 - (void)sendDistributedNotificationWithUpdatedPlaybackStatus;
 - (void)playbackModeUpdated;
diff --git a/modules/gui/macosx/intf.m b/modules/gui/macosx/intf.m
index 79d7c6e..89e6ebb 100644
--- a/modules/gui/macosx/intf.m
+++ b/modules/gui/macosx/intf.m
@@ -273,7 +273,6 @@ static void QuitVLC( void *obj )
  * Run: main loop
  *****************************************************************************/
 static NSLock * o_appLock = nil;    // controls access to f_appExit
-static NSLock * o_plItemChangedLock = nil;
 
 static void Run(intf_thread_t *p_intf)
 {
@@ -281,7 +280,6 @@ static void Run(intf_thread_t *p_intf)
     [VLCApplication sharedApplication];
 
     o_appLock = [[NSLock alloc] init];
-    o_plItemChangedLock = [[NSLock alloc] init];
     o_vout_provider_lock = [[NSLock alloc] init];
 
     libvlc_SetExitHandler(p_intf->p_libvlc, QuitVLC, p_intf);
@@ -292,7 +290,6 @@ static void Run(intf_thread_t *p_intf)
 
     [NSApp run];
     [[VLCMain sharedInstance] applicationWillTerminate:nil];
-    [o_plItemChangedLock release];
     [o_appLock release];
     [o_vout_provider_lock release];
     o_vout_provider_lock = nil;
@@ -388,13 +385,7 @@ static int PLItemChanged(vlc_object_t *p_this, const char *psz_var,
 {
     NSAutoreleasePool * o_pool = [[NSAutoreleasePool alloc] init];
 
-    /* Due to constraints within NSAttributedString's main loop runtime handling
-     * and other issues, we need to wait for -PlaylistItemChanged to finish and
-     * then -informInputChanged on this non-main thread. */
-    [o_plItemChangedLock lock];
-    [[VLCMain sharedInstance] performSelectorOnMainThread:@selector(PlaylistItemChanged) withObject:nil waitUntilDone:YES]; // MUST BE ON MAIN THREAD
-    [[VLCMain sharedInstance] informInputChanged]; // DO NOT MOVE TO MAIN THREAD
-    [o_plItemChangedLock unlock];
+    [[VLCMain sharedInstance] performSelectorOnMainThread:@selector(PlaylistItemChanged) withObject:nil waitUntilDone:NO];
 
     [o_pool release];
     return VLC_SUCCESS;
@@ -614,7 +605,7 @@ static VLCMain *_o_sharedMainInstance = nil;
         _o_sharedMainInstance = [super init];
 
     p_intf = NULL;
-    p_current_input = p_input_changed = NULL;
+    p_current_input = NULL;
 
     o_open = [[VLCOpen alloc] init];
     o_coredialogs = [[VLCCoreDialogProvider alloc] init];
@@ -635,6 +626,8 @@ static VLCMain *_o_sharedMainInstance = nil;
 
     o_vout_controller = [[VLCVoutWindowController alloc] init];
 
+    informInputChangedQueue = dispatch_queue_create("org.videolan.vlc.inputChangedQueue", DISPATCH_QUEUE_SERIAL);
+
     return _o_sharedMainInstance;
 }
 
@@ -1265,6 +1258,8 @@ static VLCMain *_o_sharedMainInstance = nil;
 // This must be called on main thread
 - (void)PlaylistItemChanged
 {
+    input_thread_t *p_input_changed = nil;
+
     if (p_current_input && (p_current_input->b_dead || !vlc_object_alive(p_current_input))) {
         var_DelCallback(p_current_input, "intf-event", InputEvent, [VLCMain sharedInstance]);
         p_input_changed = p_current_input;
@@ -1292,14 +1287,17 @@ static VLCMain *_o_sharedMainInstance = nil;
     [o_mainwindow updateWindow];
     [self updateDelays];
     [self updateMainMenu];
-}
 
-- (void)informInputChanged
-{
+    /*
+     * Due to constraints within NSAttributedString's main loop runtime handling
+     * and other issues, we need to inform the extension manager on a separate thread.
+     * The serial queue ensures that changed inputs are propagated in the same order as they arrive.
+     */
     if (p_input_changed) {
-        [[ExtensionsManager getInstance:p_intf] inputChanged:p_input_changed];
-        vlc_object_release(p_input_changed);
-        p_input_changed = NULL;
+        dispatch_async(informInputChangedQueue, ^{
+            [[ExtensionsManager getInstance:p_intf] inputChanged:p_input_changed];
+            vlc_object_release(p_input_changed);
+        });
     }
 }
 



More information about the vlc-commits mailing list