Commit 46d154e1 authored by David Fuhrmann's avatar 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 a8ff5278.

Fixes another deadlock on application termination.

close #10647
parent 6c2f54a9
...@@ -68,7 +68,7 @@ audio_output_t *getAout(void); ...@@ -68,7 +68,7 @@ audio_output_t *getAout(void);
@interface VLCMain : NSObject <NSWindowDelegate, NSApplicationDelegate> @interface VLCMain : NSObject <NSWindowDelegate, NSApplicationDelegate>
{ {
intf_thread_t *p_intf; /* The main intf object */ 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 */ BOOL launched; /* finishedLaunching */
int items_at_launch; /* items in playlist after launch */ int items_at_launch; /* items in playlist after launch */
id o_mainmenu; /* VLCMainMenu */ id o_mainmenu; /* VLCMainMenu */
...@@ -119,6 +119,8 @@ audio_output_t *getAout(void); ...@@ -119,6 +119,8 @@ audio_output_t *getAout(void);
NSTimer *o_itunes_play_timer; NSTimer *o_itunes_play_timer;
BOOL b_playlist_updated_selector_in_queue; BOOL b_playlist_updated_selector_in_queue;
dispatch_queue_t informInputChangedQueue;
} }
@property (readonly) VLCVoutWindowController* voutController; @property (readonly) VLCVoutWindowController* voutController;
...@@ -149,7 +151,6 @@ audio_output_t *getAout(void); ...@@ -149,7 +151,6 @@ audio_output_t *getAout(void);
- (BOOL)hasDefinedShortcutKey:(NSEvent *)o_event force:(BOOL)b_force; - (BOOL)hasDefinedShortcutKey:(NSEvent *)o_event force:(BOOL)b_force;
- (void)PlaylistItemChanged; - (void)PlaylistItemChanged;
- (void)informInputChanged;
- (void)playbackStatusUpdated; - (void)playbackStatusUpdated;
- (void)sendDistributedNotificationWithUpdatedPlaybackStatus; - (void)sendDistributedNotificationWithUpdatedPlaybackStatus;
- (void)playbackModeUpdated; - (void)playbackModeUpdated;
......
...@@ -273,7 +273,6 @@ static void QuitVLC( void *obj ) ...@@ -273,7 +273,6 @@ static void QuitVLC( void *obj )
* Run: main loop * Run: main loop
*****************************************************************************/ *****************************************************************************/
static NSLock * o_appLock = nil; // controls access to f_appExit static NSLock * o_appLock = nil; // controls access to f_appExit
static NSLock * o_plItemChangedLock = nil;
static void Run(intf_thread_t *p_intf) static void Run(intf_thread_t *p_intf)
{ {
...@@ -281,7 +280,6 @@ static void Run(intf_thread_t *p_intf) ...@@ -281,7 +280,6 @@ static void Run(intf_thread_t *p_intf)
[VLCApplication sharedApplication]; [VLCApplication sharedApplication];
o_appLock = [[NSLock alloc] init]; o_appLock = [[NSLock alloc] init];
o_plItemChangedLock = [[NSLock alloc] init];
o_vout_provider_lock = [[NSLock alloc] init]; o_vout_provider_lock = [[NSLock alloc] init];
libvlc_SetExitHandler(p_intf->p_libvlc, QuitVLC, p_intf); libvlc_SetExitHandler(p_intf->p_libvlc, QuitVLC, p_intf);
...@@ -292,7 +290,6 @@ static void Run(intf_thread_t *p_intf) ...@@ -292,7 +290,6 @@ static void Run(intf_thread_t *p_intf)
[NSApp run]; [NSApp run];
[[VLCMain sharedInstance] applicationWillTerminate:nil]; [[VLCMain sharedInstance] applicationWillTerminate:nil];
[o_plItemChangedLock release];
[o_appLock release]; [o_appLock release];
[o_vout_provider_lock release]; [o_vout_provider_lock release];
o_vout_provider_lock = nil; o_vout_provider_lock = nil;
...@@ -388,13 +385,7 @@ static int PLItemChanged(vlc_object_t *p_this, const char *psz_var, ...@@ -388,13 +385,7 @@ static int PLItemChanged(vlc_object_t *p_this, const char *psz_var,
{ {
NSAutoreleasePool * o_pool = [[NSAutoreleasePool alloc] init]; NSAutoreleasePool * o_pool = [[NSAutoreleasePool alloc] init];
/* Due to constraints within NSAttributedString's main loop runtime handling [[VLCMain sharedInstance] performSelectorOnMainThread:@selector(PlaylistItemChanged) withObject:nil waitUntilDone:NO];
* 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];
[o_pool release]; [o_pool release];
return VLC_SUCCESS; return VLC_SUCCESS;
...@@ -614,7 +605,7 @@ static VLCMain *_o_sharedMainInstance = nil; ...@@ -614,7 +605,7 @@ static VLCMain *_o_sharedMainInstance = nil;
_o_sharedMainInstance = [super init]; _o_sharedMainInstance = [super init];
p_intf = NULL; p_intf = NULL;
p_current_input = p_input_changed = NULL; p_current_input = NULL;
o_open = [[VLCOpen alloc] init]; o_open = [[VLCOpen alloc] init];
o_coredialogs = [[VLCCoreDialogProvider alloc] init]; o_coredialogs = [[VLCCoreDialogProvider alloc] init];
...@@ -635,6 +626,8 @@ static VLCMain *_o_sharedMainInstance = nil; ...@@ -635,6 +626,8 @@ static VLCMain *_o_sharedMainInstance = nil;
o_vout_controller = [[VLCVoutWindowController alloc] init]; o_vout_controller = [[VLCVoutWindowController alloc] init];
informInputChangedQueue = dispatch_queue_create("org.videolan.vlc.inputChangedQueue", DISPATCH_QUEUE_SERIAL);
return _o_sharedMainInstance; return _o_sharedMainInstance;
} }
...@@ -1265,6 +1258,8 @@ static VLCMain *_o_sharedMainInstance = nil; ...@@ -1265,6 +1258,8 @@ static VLCMain *_o_sharedMainInstance = nil;
// This must be called on main thread // This must be called on main thread
- (void)PlaylistItemChanged - (void)PlaylistItemChanged
{ {
input_thread_t *p_input_changed = nil;
if (p_current_input && (p_current_input->b_dead || !vlc_object_alive(p_current_input))) { 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]); var_DelCallback(p_current_input, "intf-event", InputEvent, [VLCMain sharedInstance]);
p_input_changed = p_current_input; p_input_changed = p_current_input;
...@@ -1292,14 +1287,17 @@ static VLCMain *_o_sharedMainInstance = nil; ...@@ -1292,14 +1287,17 @@ static VLCMain *_o_sharedMainInstance = nil;
[o_mainwindow updateWindow]; [o_mainwindow updateWindow];
[self updateDelays]; [self updateDelays];
[self updateMainMenu]; [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) { if (p_input_changed) {
[[ExtensionsManager getInstance:p_intf] inputChanged:p_input_changed]; dispatch_async(informInputChangedQueue, ^{
vlc_object_release(p_input_changed); [[ExtensionsManager getInstance:p_intf] inputChanged:p_input_changed];
p_input_changed = NULL; vlc_object_release(p_input_changed);
});
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment