2010-07-15 65 views
2

在我的应用我添加CFMachPortRef(通过CFMachPortCreateRunLoopSource)的线程CFRunLoopGCD和RunLoops

现在,我问我自己,可以在此使用GCD做?比方说,而不是产卵我自己NSThread并通过CFRunLoopAddSource事件端口添加创建CFRunLoopSourceRef它的运行循环,增加调度的runloop?

我认为这很可能不起作用,因为GCD的内部工作原理,但我真的不知道。

更新


我得到这个至今,但没有回调函数的事件自来水也没有dispatch_source_event_handler块被调用。有任何想法吗?

CFMachPortRef port = CGEventTapCreate(kCGSessionEventTap, 
             kCGHeadInsertEventTap, 
             opts, 
             desc_.eventMask, 
             _CGEventCallback, 
             self); 

// create dispatch source 
dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_RECV, 
                CFMachPortGetPort(port), 
                0, 
                dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)); 

// set event handler 
dispatch_source_set_event_handler(source, ^{ 
    printf("handle me!\n"); 
}); 

dispatch_resume(source); 
+0

'CFMachPort'结合了Mach端口和回调。如果您使用GCD来监控Mach端口,则忽略回调。在事件点击的情况下,回调在Core Graphics内部,大概是很重要的东西(例如接收来自端口的Mach消息,解码并调用* your * callback)。 – 2016-03-13 21:50:40

回答

2

您可以使用dispatch_source_create()函数实际使用GCD监视Mach端口。该守则将是这个样子:

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); 

每当消息进入的端口,你在传递的事件处理程序的块应该被调用,你可以有处理消息。这个例子只是使用GCD提供的全局队列来处理消息,但是如果你愿意,你可以创建一个自定义队列。

+0

不起作用(至少对于我的情况):请参阅上面的*更新*部分。 – 2010-07-16 11:59:09

+0

如果你发布“不会用事件点击这种方式工作”我可以接受你的答案:) – 2010-07-21 16:46:23

+0

我不完全确定为什么代码不会工作,我实际上没有使用GCD事件源与(我已经使用过其他类型的GCD源代码),所以我不确定是否对事件点击创建的端口有一些限制。您是否尝试了CFRunLoop的处事方式,只是为了确保至少水龙头正确地创建并在这种情况下工作? – 2010-07-21 19:49:36

0

要从GCD队列上的通知端口安排回调,您可以使用IONotificationPortSetDispatchQueue而不是将CFRunLoopAddSource与Runloop一起使用。

实施例:

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); 

这将导致处理程序myCallback()被称为在GCD队列myQueue