[vlc-commits] VLCOpenGLES2VideoView: use dedicated CFRunLoop mode
Alexandre Janniaux
git at videolan.org
Tue Apr 20 10:31:36 UTC 2021
vlc | branch: master | Alexandre Janniaux <ajanni at videolabs.io> | Thu Feb 18 15:01:12 2021 +0100| [b4c7561cadc93293fde611363379f847d3ad07a7] | committer: Alexandre Janniaux
VLCOpenGLES2VideoView: use dedicated CFRunLoop mode
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"), ..).
By adding the default mode too, it ensures it would run in the normal
CFRunLoop too.
Async tasks can still be dispatched without the "vlc_runloop" mode but
every sync task in the display must be done under this mode to prevent
deadlock from happening between the main thread and the vout_thread.
Fixes #23571
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=b4c7561cadc93293fde611363379f847d3ad07a7
---
modules/video_output/apple/VLCOpenGLES2VideoView.m | 37 ++++++++++++++++++++--
1 file changed, 34 insertions(+), 3 deletions(-)
diff --git a/modules/video_output/apple/VLCOpenGLES2VideoView.m b/modules/video_output/apple/VLCOpenGLES2VideoView.m
index fb452bba81..fc6ba8e274 100644
--- a/modules/video_output/apple/VLCOpenGLES2VideoView.m
+++ b/modules/video_output/apple/VLCOpenGLES2VideoView.m
@@ -79,6 +79,35 @@
- (void)detachFromWindow;
@end
+static void vlc_dispatch_sync(void (^block_function)())
+{
+ CFRunLoopRef runloop = CFRunLoopGetMain();
+
+ __block vlc_sem_t performed;
+ vlc_sem_init(&performed, 0);
+
+ CFStringRef modes_cfstrings[] = {
+ kCFRunLoopDefaultMode,
+ CFSTR("org.videolan.vlccore.window"),
+ };
+
+ CFArrayRef modes = CFArrayCreate(NULL, (const void **)modes_cfstrings,
+ ARRAY_SIZE(modes_cfstrings),
+ &kCFTypeArrayCallBacks);
+
+ /* NOTE: we're using CFRunLoopPerformBlock with a custom mode tag
+ * to avoid deadlocks between the window module (main thread) and the
+ * display module, which would happen when using dispatch_sycn here. */
+ CFRunLoopPerformBlock(runloop, modes, ^{
+ (block_function)();
+ vlc_sem_post(&performed);
+ });
+ CFRunLoopWakeUp(runloop);
+
+ vlc_sem_wait(&performed);
+ CFRelease(modes);
+}
+
/*****************************************************************************
* vlc_gl_t callbacks
*****************************************************************************/
@@ -466,9 +495,11 @@ static int Open(vlc_gl_t *gl, unsigned width, unsigned height)
if (wnd->type != VOUT_WINDOW_TYPE_NSOBJECT)
return VLC_EGENERIC;
- @autoreleasepool {
- /* setup the actual OpenGL ES view */
- dispatch_sync(dispatch_get_main_queue(), ^{
+ @autoreleasepool {
+ /* NOTE: we're using CFRunLoopPerformBlock with the "vlc_runloop" tag
+ * to avoid deadlocks between the window module (main thread) and the
+ * display module, which would happen when using dispatch_sycn here. */
+ vlc_dispatch_sync(^{
gl->sys = (__bridge_retained void*)[[VLCOpenGLES2VideoView alloc]
initWithFrame:CGRectMake(0.,0.,width,height) gl:gl];
});
More information about the vlc-commits
mailing list