views:

100

answers:

1

Hi everyone.

In my app I add an CFMachPortRef (via CFMachPortCreateRunLoopSource) to a threads CFRunLoop

Now i was asking myself, can this be done using GCD? Let's say instead of spawning my own NSThread and add the created CFRunLoopSourceRef to its run loop via CFRunLoopAddSource, add the event port to a dispatch's runloop?

I think this will most likely not work due to the inner workings of GCD, but I really don't know.

Best Regards, Erik

Update


I got this so far, however neither the callback function for the event tap nor the dispatch_source_event_handler block is called. Any ideas?

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

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.

Brian Webster
doesn't work (at least for my case): see *update* section above.
Erik Aigner
if you post a "won't work with this way with event taps" i can accept your answer :)
Erik Aigner
I'm not exactly sure why that code wouldn't be working, I've actually not used GCD event sources with mach ports (I've used other types of GCD sources), so I'm not sure if there's some limitation with ports created for event taps. Have you tried the CFRunLoop way of doing things, just to make sure at least the tap is getting created correctly and works in that context?
Brian Webster
Yes the CFRunLoop way works as expected, it's only the GCD style implementation that doesn't work.
Erik Aigner