[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