[vlc-commits] macosx: sanity checks and locking for video provider (fixes #8541)

David Fuhrmann git at videolan.org
Tue Apr 30 21:47:03 CEST 2013


vlc | branch: master | David Fuhrmann <david.fuhrmann at googlemail.com> | Tue Apr 30 20:27:53 2013 +0200| [6c3f33092f78e7645093f8f468756cf45bd4fde0] | committer: David Fuhrmann

macosx: sanity checks and locking for video provider (fixes #8541)

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

 modules/gui/macosx/intf.m |   70 ++++++++++++++++++++++++++++++++++-----------
 1 file changed, 54 insertions(+), 16 deletions(-)

diff --git a/modules/gui/macosx/intf.m b/modules/gui/macosx/intf.m
index 5eed8f4..fea4ff7 100644
--- a/modules/gui/macosx/intf.m
+++ b/modules/gui/macosx/intf.m
@@ -132,6 +132,8 @@ void CloseIntf (vlc_object_t *p_this)
     free(p_intf->p_sys);
 }
 
+static NSLock * o_vout_provider_lock = nil;
+
 static int WindowControl(vout_window_t *, int i_query, va_list);
 
 int WindowOpen(vout_window_t *p_wnd, const vout_window_cfg_t *cfg)
@@ -140,11 +142,19 @@ int WindowOpen(vout_window_t *p_wnd, const vout_window_cfg_t *cfg)
     intf_thread_t *p_intf = VLCIntf;
     if (!p_intf) {
         msg_Err(p_wnd, "Mac OS X interface not found");
+        [o_pool release];
         return VLC_EGENERIC;
     }
     NSRect proposedVideoViewPosition = NSMakeRect(cfg->x, cfg->y, cfg->width, cfg->height);
 
+    [o_vout_provider_lock lock];
     VLCVoutWindowController *o_vout_controller = [[VLCMain sharedInstance] voutController];
+    if (!o_vout_controller) {
+        [o_vout_provider_lock unlock];
+        [o_pool release];
+        return VLC_EGENERIC;
+    }
+
     SEL sel = @selector(setupVoutForWindow:withProposedVideoViewPosition:);
     NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[o_vout_controller methodSignatureForSelector:sel]];
     [inv setTarget:o_vout_controller];
@@ -160,6 +170,7 @@ int WindowOpen(vout_window_t *p_wnd, const vout_window_cfg_t *cfg)
 
     if (!videoView) {
         msg_Err(p_wnd, "got no video view from the interface");
+        [o_vout_provider_lock unlock];
         [o_pool release];
         return VLC_EGENERIC;
     }
@@ -167,7 +178,6 @@ int WindowOpen(vout_window_t *p_wnd, const vout_window_cfg_t *cfg)
     msg_Dbg(VLCIntf, "returning videoview with proposed position x=%i, y=%i, width=%i, height=%i", cfg->x, cfg->y, cfg->width, cfg->height);
     p_wnd->handle.nsobject = videoView;
 
-
     // TODO: find a cleaner way for "start in fullscreen"
     if (var_GetBool(pl_Get(VLCIntf), "fullscreen")) {
         int i_full = 1;
@@ -181,6 +191,7 @@ int WindowOpen(vout_window_t *p_wnd, const vout_window_cfg_t *cfg)
         [inv performSelectorOnMainThread:@selector(invoke) withObject:nil
                            waitUntilDone:NO];
     }
+    [o_vout_provider_lock unlock];
 
     [[VLCMain sharedInstance] setActiveVideoPlayback: YES];
     p_wnd->control = WindowControl;
@@ -191,10 +202,19 @@ int WindowOpen(vout_window_t *p_wnd, const vout_window_cfg_t *cfg)
 
 static int WindowControl(vout_window_t *p_wnd, int i_query, va_list args)
 {
+    NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
+
+    [o_vout_provider_lock lock];
+    VLCVoutWindowController *o_vout_controller = [[VLCMain sharedInstance] voutController];
+    if (!o_vout_controller) {
+        [o_vout_provider_lock unlock];
+        [o_pool release];
+        return VLC_EGENERIC;
+    }
+
     switch(i_query) {
         case VOUT_WINDOW_SET_STATE:
         {
-            NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
             unsigned i_state = va_arg(args, unsigned);
 
             NSInteger i_cooca_level = NSNormalWindowLevel;
@@ -202,36 +222,33 @@ static int WindowControl(vout_window_t *p_wnd, int i_query, va_list args)
                 i_cooca_level = NSStatusWindowLevel;
 
             SEL sel = @selector(setWindowLevel:forWindow:);
-            NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[[[VLCMain sharedInstance] voutController] methodSignatureForSelector:sel]];
-            [inv setTarget:[[VLCMain sharedInstance] voutController]];
+            NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[o_vout_controller methodSignatureForSelector:sel]];
+            [inv setTarget:o_vout_controller];
             [inv setSelector:sel];
             [inv setArgument:&i_cooca_level atIndex:2]; // starting at 2!
             [inv setArgument:&p_wnd atIndex:3];
             [inv performSelectorOnMainThread:@selector(invoke) withObject:nil
                                waitUntilDone:NO];
 
-            [o_pool release];
-            return VLC_SUCCESS;
+            break;
         }
         case VOUT_WINDOW_SET_SIZE:
         {
-            NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
 
             unsigned int i_width  = va_arg(args, unsigned int);
             unsigned int i_height = va_arg(args, unsigned int);
 
             NSSize newSize = NSMakeSize(i_width, i_height);
             SEL sel = @selector(setNativeVideoSize:forWindow:);
-            NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[[[VLCMain sharedInstance] voutController] methodSignatureForSelector:sel]];
-            [inv setTarget:[[VLCMain sharedInstance] voutController]];
+            NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[o_vout_controller methodSignatureForSelector:sel]];
+            [inv setTarget:o_vout_controller];
             [inv setSelector:sel];
             [inv setArgument:&newSize atIndex:2]; // starting at 2!
             [inv setArgument:&p_wnd atIndex:3];
             [inv performSelectorOnMainThread:@selector(invoke) withObject:nil
                                waitUntilDone:NO];
 
-            [o_pool release];
-            return VLC_SUCCESS;
+            break;
         }
         case VOUT_WINDOW_SET_FULLSCREEN:
         {
@@ -239,28 +256,44 @@ static int WindowControl(vout_window_t *p_wnd, int i_query, va_list args)
             int i_full = va_arg(args, int);
 
             SEL sel = @selector(setFullscreen:forWindow:);
-            NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[[[VLCMain sharedInstance] voutController] methodSignatureForSelector:sel]];
-            [inv setTarget:[[VLCMain sharedInstance] voutController]];
+            NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[o_vout_controller methodSignatureForSelector:sel]];
+            [inv setTarget:o_vout_controller];
             [inv setSelector:sel];
             [inv setArgument:&i_full atIndex:2]; // starting at 2!
             [inv setArgument:&p_wnd atIndex:3];
             [inv performSelectorOnMainThread:@selector(invoke) withObject:nil
                                waitUntilDone:NO];
 
-            [o_pool release];
-            return VLC_SUCCESS;
+            break;
         }
         default:
+        {
             msg_Warn(p_wnd, "unsupported control query");
+            [o_vout_provider_lock unlock];
+            [o_pool release];
             return VLC_EGENERIC;
+        }
     }
+
+    [o_vout_provider_lock unlock];
+    [o_pool release];
+    return VLC_SUCCESS;
 }
 
 void WindowClose(vout_window_t *p_wnd)
 {
     NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
 
-    [[[VLCMain sharedInstance] voutController] performSelectorOnMainThread:@selector(removeVoutforDisplay:) withObject:[NSValue valueWithPointer:p_wnd] waitUntilDone:NO];
+    [o_vout_provider_lock lock];
+    VLCVoutWindowController *o_vout_controller = [[VLCMain sharedInstance] voutController];
+    if (!o_vout_controller) {
+        [o_vout_provider_lock unlock];
+        [o_pool release];
+        return;
+    }
+
+    [o_vout_controller performSelectorOnMainThread:@selector(removeVoutforDisplay:) withObject:[NSValue valueWithPointer:p_wnd] waitUntilDone:NO];
+    [o_vout_provider_lock unlock];
 
     [o_pool release];
 }
@@ -278,6 +311,7 @@ static void Run(intf_thread_t *p_intf)
 
     o_appLock = [[NSLock alloc] init];
     o_plItemChangedLock = [[NSLock alloc] init];
+    o_vout_provider_lock = [[NSLock alloc] init];
 
     [[VLCMain sharedInstance] setIntf: p_intf];
 
@@ -287,6 +321,8 @@ static void Run(intf_thread_t *p_intf)
     [[VLCMain sharedInstance] applicationWillTerminate:nil];
     [o_plItemChangedLock release];
     [o_appLock release];
+    [o_vout_provider_lock release];
+    o_vout_provider_lock = nil;
     [o_pool release];
 
     raise(SIGTERM);
@@ -887,9 +923,11 @@ static VLCMain *_o_sharedMainInstance = nil;
     /* remove global observer watching for vout device changes correctly */
     [[NSNotificationCenter defaultCenter] removeObserver: self];
 
+    [o_vout_provider_lock lock];
     // release before o_info!
     [o_vout_controller release];
     o_vout_controller = nil;
+    [o_vout_provider_lock unlock];
 
     /* release some other objects here, because it isn't sure whether dealloc
      * will be called later on */



More information about the vlc-commits mailing list