Steve Lhomme pushed to branch master at VideoLAN / VLC
Commits:
feefb1d7 by Alexandre Janniaux at 2024-10-03T11:36:23+00:00
macosx: VLCMain: use CFRunLoop to avoid servicing dispatch
The main dispatch_queue is a serial queue and cannot be re-entered, so
we cannot start the NSApp runloop there since it will block into the
callback while servicing the main queue, and thus no more blocks will
be able to be executed on this main dispatch_queue. It is visible with
the callstack there:
thread #1, queue = 'com.apple.main-thread'
frame #0: 0x0000000183c3e1f4 libsystem_kernel.dylib`mach_msg2_trap + 8
frame #1: 0x0000000183c50b24 libsystem_kernel.dylib`mach_msg2_internal
+ 80
frame #2: 0x0000000183c46e34 libsystem_kernel.dylib`mach_msg_overwrite
+ 476
frame #3: 0x0000000183c3e578 libsystem_kernel.dylib`mach_msg + 24
frame #4: 0x0000000183d5e680 CoreFoundation`__CFRunLoopServiceMachPort
+ 160
frame #5: 0x0000000183d5cf44 CoreFoundation`__CFRunLoopRun + 1208
frame #6: 0x0000000183d5c434 CoreFoundation`CFRunLoopRunSpecific + 608
frame #7: 0x000000018e50019c HIToolbox`RunCurrentEventLoopInMode + 292
frame #8: 0x000000018e4fffd8 HIToolbox`ReceiveNextEventCommon + 648
frame #9: 0x000000018e4ffd30
HIToolbox`_BlockUntilNextEventMatchingListInModeWithFilter + 76
frame #10: 0x00000001875bbd68 AppKit`_DPSNextEvent + 660
frame #11: 0x0000000187db1808 AppKit`-[NSApplication(NSEventRouting)
_nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 700
frame #12: 0x00000001875af09c AppKit`-[NSApplication run] + 476
frame #13: 0x00000001030b791c
libmacosx_plugin.dylib`__OpenIntf_block_invoke_2(.block_descriptor=<unavailable>)
at VLCMain.m:166:17 [opt]
frame #14: 0x0000000183acc750
libdispatch.dylib`_dispatch_call_block_and_release + 32
frame #15: 0x0000000183ace3e8
libdispatch.dylib`_dispatch_client_callout + 20
frame #16: 0x0000000183adcbb8
libdispatch.dylib`_dispatch_main_queue_drain + 988
frame #17: 0x0000000183adc7cc
libdispatch.dylib`_dispatch_main_queue_callback_4CF + 44
frame #18: 0x0000000183d9fad4
CoreFoundation`__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 16
frame #19: 0x0000000183d5d258 CoreFoundation`__CFRunLoopRun + 1996
frame #20: 0x0000000183d5c434 CoreFoundation`CFRunLoopRunSpecific + 608
frame #21: 0x0000000183dda45c CoreFoundation`CFRunLoopRun + 64
frame #22: 0x0000000100003084 vlc-osx-static`main(i_argc=1,
ppsz_argv=0x000000016fdff0c8) at darwinvlc.m:309:9 [opt]
frame #23: 0x00000001838f60e0 dyld`start + 2360
By running the CFRunLoop instead, we don't have this serial execution
constraint and can re-enter the loop while servicing the main dispatch
queue from inside the [NSApp run] runloop. It now has the following
callstack when running:
thread #1, queue = 'com.apple.main-thread', stop reason = signal
SIGSTOP
frame #0: 0x0000000183c3e1f4 libsystem_kernel.dylib`mach_msg2_trap + 8
frame #1: 0x0000000183c50b24 libsystem_kernel.dylib`mach_msg2_internal
+ 80
frame #2: 0x0000000183c46e34 libsystem_kernel.dylib`mach_msg_overwrite
+ 476
frame #3: 0x0000000183c3e578 libsystem_kernel.dylib`mach_msg + 24
frame #4: 0x0000000183d5e680 CoreFoundation`__CFRunLoopServiceMachPort
+ 160
frame #5: 0x0000000183d5cf44 CoreFoundation`__CFRunLoopRun + 1208
frame #6: 0x0000000183d5c434 CoreFoundation`CFRunLoopRunSpecific + 608
frame #7: 0x000000018e50019c HIToolbox`RunCurrentEventLoopInMode + 292
frame #8: 0x000000018e4fffd8 HIToolbox`ReceiveNextEventCommon + 648
frame #9: 0x000000018e4ffd30
HIToolbox`_BlockUntilNextEventMatchingListInModeWithFilter + 76
frame #10: 0x00000001875bbd68 AppKit`_DPSNextEvent + 660
frame #11: 0x0000000187db1808 AppKit`-[NSApplication(NSEventRouting)
_nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 700
frame #12: 0x00000001875af09c AppKit`-[NSApplication run] + 476
frame #13: 0x00000001030b76c8
libmacosx_plugin.dylib`__OpenIntf_block_invoke(.block_descriptor=0x00006000038813c0)
at VLCMain.m:166:13 [opt]
frame #14: 0x0000000183d5e070
CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 28
frame #15: 0x0000000183d5df84 CoreFoundation`__CFRunLoopDoBlocks + 356
frame #16: 0x0000000183d5d414 CoreFoundation`__CFRunLoopRun + 2440
frame #17: 0x0000000183d5c434 CoreFoundation`CFRunLoopRunSpecific + 608
frame #18: 0x0000000183dda45c CoreFoundation`CFRunLoopRun + 64
frame #19: 0x0000000100003084 vlc-osx-static`main(i_argc=1,
ppsz_argv=0x000000016fdff0c8) at darwinvlc.m:309:9 [opt]
frame #20: 0x00000001838f60e0 dyld`start + 2360
And now dispatch will correctly work inside this.
Regression from 3a6bd45b9e8d1f4c5e24b6031a8df44523e6c4b1 which
introduced the dispatch call and then changed also in
9cae3668c7fc1fc00939f0683c0c2293556a8d39 which also modified the
dispatch call in the destructor.
Fixes #28812
- - - - -
0b2a6f48 by Alexandre Janniaux at 2024-10-03T11:36:23+00:00
qt: use CFRunLoop to avoid servicing dispatch
The main dispatch_queue is a serial queue and cannot be re-entered, so
we cannot start the QApplication there since it will block into
a callback while servicing the main queue, and thus no more blocks will
be able to be executed on this main dispatch_queue.
By running the CFRunLoop instead, we don't have this serial execution
constraint and can re-enter the loop while servicing the main dispatch
queue from inside the QApplication runloop.
Regression from 9cae3668c7fc1fc00939f0683c0c2293556a8d39 which
introduced the dispatch call.
- - - - -
2 changed files:
- modules/gui/macosx/main/VLCMain.m
- modules/gui/qt/qt.cpp
Changes:
=====================================
modules/gui/macosx/main/VLCMain.m
=====================================
@@ -142,7 +142,8 @@ intf_thread_t *getIntf()
int OpenIntf (vlc_object_t *p_this)
{
__block int retcode = VLC_SUCCESS;
- dispatch_sync(dispatch_get_main_queue(), ^{
+ __block dispatch_semaphore_t sem = dispatch_semaphore_create(0);
+ CFRunLoopPerformBlock(CFRunLoopGetMain(), kCFRunLoopDefaultMode, ^{
@autoreleasepool {
intf_thread_t *p_intf = (intf_thread_t*) p_this;
p_interface_thread = p_intf;
@@ -161,11 +162,13 @@ int OpenIntf (vlc_object_t *p_this)
retcode = VLC_EGENERIC;
return;
}
- dispatch_async(dispatch_get_main_queue(), ^{
- [NSApp run];
- });
+ dispatch_semaphore_signal(sem);
+ [NSApp run];
}
});
+ CFRunLoopWakeUp(CFRunLoopGetMain());
+
+ dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
return retcode;
}
=====================================
modules/gui/qt/qt.cpp
=====================================
@@ -536,10 +536,9 @@ static void *Thread( void * );
static void *ThreadCleanup( qt_intf_t *p_intf, CleanupReason cleanupReason );
#ifdef Q_OS_MAC
-static void ThreadDarwin(void *);
/* Used to abort the app.exec() on OSX after libvlc_Quit is called */
#include "../../../lib/libvlc_internal.h" /* libvlc_SetExitHandler */
-#include <dispatch/dispatch.h>
+#include <CoreFoundation/CFRunLoop.h>
static void Abort( void *obj )
{
(void)obj;
@@ -600,7 +599,10 @@ static int OpenInternal( qt_intf_t *p_intf )
#ifdef Q_OS_MAC
/* Run mainloop on the main thread as Cocoa requires */
libvlc_SetExitHandler( vlc_object_instance(p_intf), Abort, p_intf );
- dispatch_async_f(dispatch_get_main_queue(), static_cast<void*>(p_intf),
ThreadDarwin);
+ CFRunLoopPerformBlock(CFRunLoopGetMain(), kCFRunLoopDefaultMode, ^{
+ Thread(static_cast<void*>(p_intf));
+ });
+ CFRunLoopWakeUp(CFRunLoopGetMain());
#else
if( vlc_clone( &p_intf->thread, Thread, p_intf ) )
{
@@ -1068,13 +1070,6 @@ static void *Thread( void *obj )
return ThreadCleanup( p_intf, CLEANUP_APP_TERMINATED );
}
-#ifdef Q_OS_MAC
-static void ThreadDarwin(void *opaque)
-{
- Thread(opaque);
-}
-#endif
-
static void *ThreadCleanup( qt_intf_t *p_intf, CleanupReason cleanupReason )
{
{
View it on GitLab:
https://code.videolan.org/videolan/vlc/-/compare/9285760f0c260679262d3976d833b63f2d66e33e...0b2a6f48bd062d9b77164e14d731aa79abed3ae1
--
View it on GitLab:
https://code.videolan.org/videolan/vlc/-/compare/9285760f0c260679262d3976d833b63f2d66e33e...0b2a6f48bd062d9b77164e14d731aa79abed3ae1
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance_______________________________________________
vlc-commits mailing list
[email protected]
https://mailman.videolan.org/listinfo/vlc-commits