I'm writing a simple application that should be able to receive and process notifications in a background thread using Apple's CoreFoundation framework. Here is what I'm trying to accomplish:
static void DummyCallback(CFNotificationCenterRef center,
void *observer,
CFStringRef name,
const void *object,
CFDictionaryRef userInfo) {
printf("RECEIVED NOTIFICATION\n");
}
void *ThreadStart(void *arg) {
CFNotificationCenterAddObserver(CFNotificationCenterGetDistributedCenter(),
NULL,
&DummyCallback,
NULL,
CFSTR("TEST_OBJECT"),
CFNotificationSuspensionBehaviorDeliverImmediately);
printf("background thread: run run loop (should take 5 sec to exit)\n");
int retval = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 5, true);
printf("background thread: exited from run loop (retval: %d)\n", retval);
return NULL;
}
int main(int argc, char** argv) {
pthread_t thread;
int rc = pthread_crea开发者_C百科te(&thread, NULL, &ThreadStart, NULL);
assert(rc == 0);
printf("main: sleep\n");
sleep(10);
printf("main: done sleeping\n");
return 0;
}
If I run the program I just get
main: sleep
background thread: run run loop (should take 5 sec to exit)
background thread: exited from run loop (retval: 1)
main: done sleeping
The problem is that the background thread's run loop exits immediately (return code kCFRunLoopRunFinished instead of kCFRunLoopRunTimedOut) because there is no source/observer/timer. CFNotificationCenterAddObserver registers itself only with the run loop of the main thread but not the one of my background thread.
I need the main thread for some other stuff and can't use it to run it's run loop. Is there any way to get this working? Maybe by registering CFNotificationCenter with the run loop of the background thread?
Thanks in advance!
As stated in http://developer.apple.com/library/mac/#documentation/CoreFoundation/Reference/CFNotificationCenterRef/Reference/reference.html
The first time an observer is registered with a distributed notification center, the notification center creates a connection with the system-wide notification server and places a listening port into the common modes of the current thread’s run loop. When a notification is delivered, it is processed on this initial thread, even if the observer that is receiving the notification registered for the notification on a different thread.
Because loaded frameworks may potentially spawn threads and add their own observers before your code executes, you cannot know for certain which thread will receive distributed notifications. If you need to control which thread processes a notification, your callback function must be able to forward the notification to the proper thread. You can use a CFMessagePort object or a custom CFRunLoopSource object to send notifications to the correct thread’s run loop.
精彩评论