GCD and RunLoops

我只是一个虾纸丫 提交于 2019-12-06 05:09:40

You can actually use GCD to monitor a Mach port, using the dispatch_source_create() function. The code would look something like this:

mach_port_t myPort; //assume you have this already
dispatch_source_t portSource;

portSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_RECV, myPort, 0, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT));
dispatch_source_set_event_handler(portSource, ^(void) { //code for handling incoming message here });

dispatch_resume(portSource);

Whenever a message comes into the port, the block you pass in as the event handler should get called, and you can handle the message there. This example just uses the global queue provided by GCD to handle the message, but you can create a custom queue if you'd like.

To schedule the callbacks from a notification port on a GCD queue you can use IONotificationPortSetDispatchQueue instead of using CFRunLoopAddSource with a Runloop.

Example:

IOServiceOpen(driver, mach_task_self(), 0, &connection);

notifyPort = IONotificationPortCreate(kIOMasterPortDefault);

IOServiceAddInterestNotification(
  notifyPort,
  driver,
  kIOGeneralInterest,
  myCallback,
  NULL, //refcon
  &notificationObject
);

// Instead of this:
// CFRunLoopAddSource(CFRunLoopGetCurrent(),
//                    IONotificationPortGetRunLoopSource(notifyPort),
//                    kCFRunLoopDefaultMode);
// do this:
IONotificationPortSetDispatchQueue(notifyPort, myQueue);

This will cause the myCallback() handler to be called on the GCD queue myQueue.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!