I am trying to build an application that must manage its own run loop. I would like to use libdispatch in this application. However, using libdispatch requires calling dispatch_main() which is a blocking method. I cannot block on the main thread.
- Is there a way to integrate custom run loops with libdispatch without using the blocking dispatch_main()?
- I see references to _dispatch_main_queue_callback_4CF in queue.c of libdispatch which looks promising. Is there a way to use this method to achieve the same? Documentation on this method is quite sparse.
- Ideally, I should not need to use an NSRunLoop/CFRunLoop.
libdispatch does not require calling
dispatch_main(), it integrates with the main thread’s runloop through the dispatch main queue, seedispatch_get_main_queue(3)and theCOMPATIBILITYsection therein.Executables that do not call
dispatch_main()and want to use the main queue must run the main thread runloop in one of the common modes for blocks on the dispatch main queue to be processed; either indirectly via standard framework methods (e.g.NSApplicationMain()) or directly via CFRunLoop or NSRunLoop APIs.Please do not attempt to use the
_dispatch_main_queue_callback_4CFsymbol, it is an implementation detail internal to the library that is very likely to change in the future and any code that relies on it will break without warning.Integration of libdispatch with custom non-main-thread CFRunLoops can be achieved in a number of ways, such as via the
CFRunLoopPerformBlock()API or custom runloop sources.Update: on Linux, you’ll have to modify the libdispatch sources, there is no existing support for interoperating with custom runloops AFAIK.
The simplest way to integrate the main queue with an existing runloop on Linux is probably indeed going to be to call the (preferably renamed)
_dispatch_main_queue_callback_4CF()function each time through the event loop, and replace_dispatch_queue_wakeup_main()with whatever method is appropriate to wake your runloop (e.g. write to a pipe the runloop is waiting on).