- if (msgid == MACH_NOTIFY_NO_SENDERS) {
- /* the server died, disable additional callbacks */
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" notifier port closed, disabling notifier"));
- } else if (cbFunc == NULL) {
- /* there is no (longer) a callback function, disable additional callbacks */
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" no callback function, disabling notifier"));
- } else {
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" executing notifiction function"));
- if ((*cbFunc)(store, cbArg)) {
- /*
- * callback function returned success.
- */
- return;
- } else {
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" callback returned error, disabling notifier"));
- }
- }
-
-#ifdef DEBUG
- if (port != storePrivate->callbackPort) {
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR("informCallback, why is port != callbackPort?"));
- }
-#endif /* DEBUG */
-
- /* remove the run loop source */
- CFRunLoopRemoveSource(CFRunLoopGetCurrent(),
- storePrivate->callbackRunLoopSource,
- kCFRunLoopDefaultMode);
- CFRelease(storePrivate->callbackRunLoopSource);
-
- /* invalidate port */
- CFMachPortInvalidate(storePrivate->callbackPort);
- CFRelease(storePrivate->callbackPort);
-
- /* disable notifier */
- storePrivate->notifyStatus = NotifierNotRegistered;
- storePrivate->callbackArgument = NULL;
- storePrivate->callbackFunction = NULL;
- storePrivate->callbackPort = NULL;
- storePrivate->callbackRunLoop = NULL;
- storePrivate->callbackRunLoopSource = NULL;
-
- return;
-}
-
-
-Boolean
-SCDynamicStoreNotifyCallback(SCDynamicStoreRef store,
- CFRunLoopRef runLoop,
- SCDynamicStoreCallBack_v1 func,
- void *arg)
-{
- SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
- kern_return_t status;
- mach_port_t port;
- mach_port_t oldNotify;
- int sc_status;
- CFMachPortContext context = { 0
- , (void *)store
- , CFRetain
- , CFRelease
- , NULL
- };
-
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCDynamicStoreNotifyCallback:"));
-
- if (!store) {
- /* sorry, you must provide a session */
- _SCErrorSet(kSCStatusNoStoreSession);
- return FALSE;
- }
-
- if (storePrivate->server == MACH_PORT_NULL) {
- /* sorry, you must have an open session to play */
- _SCErrorSet(kSCStatusNoStoreServer);
- return FALSE;
- }
-
- if (storePrivate->notifyStatus != NotifierNotRegistered) {
- /* sorry, you can only have one notification registered at once */
- _SCErrorSet(kSCStatusNotifierActive);
- return FALSE;
- }
-
- /* Allocating port (for server response) */
- storePrivate->callbackPort = CFMachPortCreate(NULL,
- informCallback,
- &context,
- NULL);
-
- /* Request a notification when/if the server dies */
- port = CFMachPortGetPort(storePrivate->callbackPort);
- status = mach_port_request_notification(mach_task_self(),
- port,
- MACH_NOTIFY_NO_SENDERS,
- 1,
- port,
- MACH_MSG_TYPE_MAKE_SEND_ONCE,
- &oldNotify);
- if (status != KERN_SUCCESS) {
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR("mach_port_request_notification(): %s"), mach_error_string(status));
- CFMachPortInvalidate(storePrivate->callbackPort);
- CFRelease(storePrivate->callbackPort);
- _SCErrorSet(status);
- return FALSE;
- }
-
- if (oldNotify != MACH_PORT_NULL) {
- SCLog(_sc_verbose, LOG_ERR, CFSTR("SCDynamicStoreNotifyCallback(): why is oldNotify != MACH_PORT_NULL?"));
- }
-
- /* Requesting notification via mach port */
- status = notifyviaport(storePrivate->server,
- port,
- 0,
- (int *)&sc_status);
-
- if (status != KERN_SUCCESS) {
- if (status != MACH_SEND_INVALID_DEST)
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR("notifyviaport(): %s"), mach_error_string(status));
- CFMachPortInvalidate(storePrivate->callbackPort);
- CFRelease(storePrivate->callbackPort);
- (void) mach_port_destroy(mach_task_self(), storePrivate->server);
- storePrivate->server = MACH_PORT_NULL;
- _SCErrorSet(status);
- return FALSE;
- }
-
- if (sc_status != kSCStatusOK) {
- _SCErrorSet(sc_status);
- return FALSE;
- }
-
- /* set notifier active */
- storePrivate->notifyStatus = Using_NotifierInformViaCallback;
-
- /* Creating/adding a run loop source for the port */
- storePrivate->callbackArgument = arg;
- storePrivate->callbackFunction = func;
- storePrivate->callbackRunLoop = runLoop;
- storePrivate->callbackRunLoopSource =
- CFMachPortCreateRunLoopSource(NULL, storePrivate->callbackPort, 0);
-
- CFRunLoopAddSource(storePrivate->callbackRunLoop,
- storePrivate->callbackRunLoopSource,
- kCFRunLoopDefaultMode);
-
- return TRUE;