[vlc-devel] [PATCH 1/3] VLCVidewUIView: report event in another thread

Alexandre Janniaux ajanni at videolabs.io
Thu Feb 18 18:34:52 UTC 2021


A few updates:

- we should probably use a better name for the mode, like
  org.videolan.vlccore.window
- maybe have the name somewhere global? it's a bit annoying
  to expose it though. Maybe behind a private API header for
  queuing blocks?
- use another thread provider than dispatch_get_global_queue?

Regards,
--
Alexandre Janniaux
Videolabs

On Thu, Feb 18, 2021 at 04:23:54PM +0100, Alexandre Janniaux wrote:
> Report events from a different thread than the main thread, and continue
> to execute the main CFRunLoop, but filter the events to only executes
> the ones queued by potential display, ie. those tagged with the mode
> "vlc_runloop".
>
> The vlc_runloop mode is designed to be executed even when an event is
> being reported by the vout_window used, ie. when there is a call to
> CFRunLoopInMode(CFRunLoopGetMain(), CFSTR("vlc_runloop"), ..).
>
> Clients should ensure they also tag their blocks with the default mode
> too. Otherwise, they are likely to never be executed.
>
> Async tasks can still be dispatched without the "vlc_runloop" mode but
> every sync tasks in the display must be done under this mode to prevent
> deadlock from happening between the main thread and the vout_thread,
> typically with the following code:
>
>     /* The main loop to run the block into */
>     CFRunLoopRef runloop = CFRunLoopGetMain();
>
>     /* The modes to execute the block in */
>     CFStringRef modes_cfstrings[] = { kCFRunLoopDefaultMode, CFSTR("vlc_runloop") };
>     CFArrayRef modes = CFArrayCreate(NULL, (const void **)modes_cfstrings,
>             ARRAY_SIZE(modes_cfstrings), &kCFTypeArrayCallBacks);
>
>     CFRunLoopPerformBlock(runloop, modes, ^{
>         /* The block content to execute */
>     });
>
>     /* Don't forget to signal the runloop
>     CFRunLoopWakeUp(runloop);
>     CFRelease(modes);
>
> To achieve a blocking/sync behaviour, clients can share a binary
> semaphore between the block and the outside of the block. When using a
> vlc_sem_t object, it must be qualified with __block to be modified
> inside of the block.
>
> Refs #23571
> ---
>  modules/video_output/apple/VLCVideoUIView.m | 46 ++++++++++++++++-----
>  1 file changed, 35 insertions(+), 11 deletions(-)
>
> diff --git a/modules/video_output/apple/VLCVideoUIView.m b/modules/video_output/apple/VLCVideoUIView.m
> index 3a4c749816..69993013b3 100644
> --- a/modules/video_output/apple/VLCVideoUIView.m
> +++ b/modules/video_output/apple/VLCVideoUIView.m
> @@ -161,6 +161,20 @@
>      }
>  }
>
> +- (void)reportEvent:(void(^)())eventBlock
> +{
> +    CFStringRef mode = CFSTR("vlc_runloop");
> +    CFRunLoopRef runloop = CFRunLoopGetCurrent();
> +    CFRunLoopPerformBlock(runloop, mode, ^{
> +        dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^{
> +            (eventBlock)();
> +            CFRunLoopStop(runloop);
> +        });
> +    });
> +    CFRunLoopWakeUp(runloop);
> +    CFRunLoopRunInMode(mode, 0, NO);
> +}
> +
>  - (void)detachFromParent
>  {
>      /* We need to lock because we consider that _wnd might be destroyed
> @@ -263,11 +277,16 @@
>      /* We need to lock to ensure _wnd is still valid, see detachFromParent. */
>      vlc_mutex_lock(&_mutex);
>      if (_wnd == NULL)
> -        goto end;
> -    vout_window_ReportSize(_wnd,
> -            viewSize.width * scaleFactor,
> -            viewSize.height * scaleFactor);
> -end:
> +    {
> +        vlc_mutex_unlock(&_mutex);
> +        return;
> +    }
> +
> +    [self reportEvent:^{
> +        vout_window_ReportSize(_wnd,
> +                viewSize.width * scaleFactor,
> +                viewSize.height * scaleFactor);
> +    }];
>      vlc_mutex_unlock(&_mutex);
>  }
>
> @@ -280,12 +299,17 @@ end:
>      /* We need to lock to ensure _wnd is still valid, see detachFromParent. */
>      vlc_mutex_lock(&_mutex);
>      if (_wnd == NULL)
> -        goto end;
> -    vout_window_ReportMouseMoved(_wnd,
> -            (int)touchPoint.x * scaleFactor, (int)touchPoint.y * scaleFactor);
> -    vout_window_ReportMousePressed(_wnd, MOUSE_BUTTON_LEFT);
> -    vout_window_ReportMouseReleased(_wnd, MOUSE_BUTTON_LEFT);
> -end:
> +    {
> +        vlc_mutex_unlock(&_mutex);
> +        return;
> +    }
> +
> +    [self reportEvent:^{
> +        vout_window_ReportMouseMoved(_wnd,
> +                (int)touchPoint.x * scaleFactor, (int)touchPoint.y * scaleFactor);
> +        vout_window_ReportMousePressed(_wnd, MOUSE_BUTTON_LEFT);
> +        vout_window_ReportMouseReleased(_wnd, MOUSE_BUTTON_LEFT);
> +    }];
>      vlc_mutex_unlock(&_mutex);
>  }
>
> --
> 2.30.1
>


More information about the vlc-devel mailing list