I am working on some code that uses IOConnectCallAsyncScalarMethod() to get callbacks from a DriverKit extension. The setup is quite heavy, involving spawning a thread, manually creating a CFMachPortRef, adding its CFRunLoopSourceRef to a CFRunLoop and then pumping that run loop.
In order to simplify this code and reduce the risk of race conditions, I would like to get the IOKit callback on a dispatch queue instead. Is there any way to achieve this?
After going back and forth on this unsuccessfully, I finally found the answer in the OS X and iOS Kernel Programming book (page 95, listing 5-15).
The trick is to use a
IONotificationPortRefalong withIONotificationPortSetDispatchQueueto set the target dispatch queue. Then to actually have the callback dispatched to that queue, set up anio_async_ref64_tand use it. Here's an outline of what the code would look like:callbackshould have this signature:void commandReadyCallback(void *context, IOReturn result). (AKA.IOAsyncCallback0)I hope this helps some poor soul in the future.