Regarding dispatch_get_main_queue() and the thread it is actual executing on
Hi everyone, During my work for libDispatch I had to find a way for implementing TSD de-allocators (which are not available on windows). While doing so I did some extensive debugging on OS X / Linux for understanding what is actually happening when calling dispatch_main(). Weird enough it seemed to me as if the main thread would never execute an item from the main queue but simply go to sleep instead. To verify this behaviour, I wrote a test to compare the pthread_t handles during execution: static pthread_t main_thread; void pass(void* dt){ pthread_t now = pthread_self(); assert(pthread_equal(now, main_thread) == 1); exit(0); } void dispatch_api() { dispatch_queue_t q = NULL; main_thread = pthread_self(); q = dispatch_get_main_queue(); assert(q != NULL); dispatch_async_f(q, NULL, pass); ... dispatch_main(); } This test is approving my suspicions, as the pthread_equal(...) assertion is constantly failing. So the big question is: What am I missing? I thought the main queue is available as a mean to be sure some blocks execute on the main thread (e.g. when updating the GUI is only possible while being on the main thread). I welcome any hints or help. - Marius Zwicker
On Apr 19, 2011, at 8:07 AM, Marius Zwicker wrote:
I thought the main queue is available as a mean to be sure some blocks execute on the main thread (e.g. when updating the GUI is only possible while being on the main thread).
Marius, That is only true if-and-only-if GCD is working in compatibility mode with Cocoa GUI logic, which for legacy reasons is bound to the main thread. If dispatch_main() is called, then GCD turns the main queue into a normal serial queue, with all of the performance advantages thereof. davez
On Apr 19, 2011, at 9:09 AM, Dave Zarzycki wrote:
On Apr 19, 2011, at 8:07 AM, Marius Zwicker wrote:
I thought the main queue is available as a mean to be sure some blocks execute on the main thread (e.g. when updating the GUI is only possible while being on the main thread).
Marius,
That is only true if-and-only-if GCD is working in compatibility mode with Cocoa GUI logic, which for legacy reasons is bound to the main thread. If dispatch_main() is called, then GCD turns the main queue into a normal serial queue, with all of the performance advantages thereof.
P.S. – This is covered in the dispatch_main() man page: COMPATIBILITY Cocoa applications need not call dispatch_main(). Blocks submitted to the main queue will be executed as part of the "common modes" of the application's main NSRunLoop or CFRunLoop. However, blocks submitted to the main queue in applications using dispatch_main() are not guaranteed to execute on the main thread.
Am 19.04.2011 um 18:27 schrieb Dave Zarzycki:
On Apr 19, 2011, at 9:09 AM, Dave Zarzycki wrote:
On Apr 19, 2011, at 8:07 AM, Marius Zwicker wrote:
I thought the main queue is available as a mean to be sure some blocks execute on the main thread (e.g. when updating the GUI is only possible while being on the main thread).
Marius,
That is only true if-and-only-if GCD is working in compatibility mode with Cocoa GUI logic, which for legacy reasons is bound to the main thread. If dispatch_main() is called, then GCD turns the main queue into a normal serial queue, with all of the performance advantages thereof.
P.S. – This is covered in the dispatch_main() man page:
COMPATIBILITY Cocoa applications need not call dispatch_main(). Blocks submitted to the main queue will be executed as part of the "common modes" of the application's main NSRunLoop or CFRunLoop. However, blocks submitted to the main queue in applications using dispatch_main() are not guaranteed to execute on the main thread.
Thanks a lot for the information. I will try to implement similar functionality when using gui frameworks needing a "real" main thread as well. I assume the portions you were talking about can be found when searching for the DISPATCH_COCOA_COMPAT macro.
On Apr 19, 2011, at 11:04 AM, Marius Zwicker wrote:
Am 19.04.2011 um 18:27 schrieb Dave Zarzycki:
On Apr 19, 2011, at 9:09 AM, Dave Zarzycki wrote:
On Apr 19, 2011, at 8:07 AM, Marius Zwicker wrote:
I thought the main queue is available as a mean to be sure some blocks execute on the main thread (e.g. when updating the GUI is only possible while being on the main thread).
Marius,
That is only true if-and-only-if GCD is working in compatibility mode with Cocoa GUI logic, which for legacy reasons is bound to the main thread. If dispatch_main() is called, then GCD turns the main queue into a normal serial queue, with all of the performance advantages thereof.
P.S. – This is covered in the dispatch_main() man page:
COMPATIBILITY Cocoa applications need not call dispatch_main(). Blocks submitted to the main queue will be executed as part of the "common modes" of the application's main NSRunLoop or CFRunLoop. However, blocks submitted to the main queue in applications using dispatch_main() are not guaranteed to execute on the main thread.
Thanks a lot for the information. I will try to implement similar functionality when using gui frameworks needing a "real" main thread as well. I assume the portions you were talking about can be found when searching for the DISPATCH_COCOA_COMPAT macro.
Marius, Indeed! :-) In short, we worked with our GUI team to have a kernel handle (in this case a Mach port, but it could easily be a Unix descriptor too). When that handle receives a message (or becomes readable in the case of a Unix descriptor), then they promise to call _dispatch_main_queue_callback_4CF() where CF is the common shorthand for the name of the library calling this API. You'd want to add your own equivalent with whatever arguments make sense. For example: _dispatch_main_queue_callback_4{GTK,KDE,X11,etc}(). We use the _4[A-Z][A-Z0-9*] suffix style to signify one-to-one contracts with other subsystems, and not general purpose API. davez
participants (2)
-
Dave Zarzycki
-
Marius Zwicker