static void setup_inotify_watcher(rwvx_instance_ptr_t rwvx) { RW_ASSERT(rwvx); rwvx->pacemaker_inotify.fd = inotify_init(); RW_ASSERT(rwvx->pacemaker_inotify.fd >= 0); int inotify_wd = inotify_add_watch( rwvx->pacemaker_inotify.fd, "/tmp/corosync", IN_MODIFY); RW_ASSERT(inotify_wd >= 0); CFSocketContext cf_context = { 0, rwvx, NULL, NULL, NULL }; CFOptionFlags cf_callback_flags = kCFSocketReadCallBack; CFOptionFlags cf_option_flags = kCFSocketAutomaticallyReenableReadCallBack; // Release cfsource if (rwvx->pacemaker_inotify.cfsource) { RW_CF_TYPE_VALIDATE(rwvx->pacemaker_inotify.cfsource, rwsched_CFRunLoopSourceRef); rwsched_tasklet_CFSocketReleaseRunLoopSource( rwvx->rwsched_tasklet, rwvx->pacemaker_inotify.cfsource); } // Release the cfsocket if (rwvx->pacemaker_inotify.cfsocket) { RW_CF_TYPE_VALIDATE(rwvx->pacemaker_inotify.cfsocket, rwsched_CFSocketRef); // Invalidate the cfsocket rwsched_tasklet_CFSocketInvalidate( rwvx->rwsched_tasklet, rwvx->pacemaker_inotify.cfsocket); // Release the cfsocket rwsched_tasklet_CFSocketRelease( rwvx->rwsched_tasklet, rwvx->pacemaker_inotify.cfsocket); } rwvx->pacemaker_inotify.cfsocket = rwsched_tasklet_CFSocketCreateWithNative( rwvx->rwsched_tasklet, kCFAllocatorSystemDefault, rwvx->pacemaker_inotify.fd, cf_callback_flags, pacemaker_state_changed, &cf_context); RW_CF_TYPE_VALIDATE(rwvx->pacemaker_inotify.cfsocket, rwsched_CFSocketRef); rwsched_tasklet_CFSocketSetSocketFlags( rwvx->rwsched_tasklet, rwvx->pacemaker_inotify.cfsocket, cf_option_flags); rwvx->pacemaker_inotify.cfsource = rwsched_tasklet_CFSocketCreateRunLoopSource( rwvx->rwsched_tasklet, kCFAllocatorSystemDefault, rwvx->pacemaker_inotify.cfsocket, 0); RW_CF_TYPE_VALIDATE(rwvx->pacemaker_inotify.cfsource, rwsched_CFRunLoopSourceRef); rwsched_tasklet_CFRunLoopAddSource( rwvx->rwsched_tasklet, rwsched_tasklet_CFRunLoopGetCurrent(rwvx->rwsched_tasklet), rwvx->pacemaker_inotify.cfsource, rwvx->rwsched->main_cfrunloop_mode); }
uint64_t rwmsg_toyfd_add(rwmsg_toytask_t *toy, int fd, int pollbits, toyfd_cb_t cb, void *ud) { rwsched_instance_ptr_t instance; rwmsg_toytask_t *toytask = toy; //rwsched_dispatch_source_t source; struct rwmsg_toyfd_s *toyfd; // Validate input parameters RW_CF_TYPE_VALIDATE(toytask, rwtoytask_tasklet_ptr_t); // Get the rwsched instance from the toytask instance = toytask->toysched->rwsched_instance; RW_CF_TYPE_VALIDATE(instance, rwsched_instance_ptr_t); // Allocate a toyfd container type and track it toyfd = RW_CF_TYPE_MALLOC0(sizeof(*toyfd), rwmsg_toyfd_ptr_t); RW_CF_TYPE_VALIDATE(toyfd, rwmsg_toyfd_ptr_t); // Example of using CFSocket to manage file descriptors on a runloop using CFStreamCreatePairWithSocket() // http://lists.apple.com/archives/macnetworkprog/2003/Jul/msg00075.html CFSocketContext cf_context = { 0, NULL, NULL, NULL, NULL }; CFOptionFlags cf_callback_flags = 0; CFOptionFlags cf_option_flags = 0; rwsched_CFRunLoopRef runloop = rwsched_tasklet_CFRunLoopGetCurrent(toytask->rwsched_tasklet_info); rwsched_CFSocketRef cfsocket; rwsched_CFRunLoopSourceRef cfsource; // Use the pollbits to determine which socket callback events to register if (pollbits & POLLIN) { cf_callback_flags |= kCFSocketReadCallBack; cf_option_flags |= kCFSocketAutomaticallyReenableReadCallBack; } if (pollbits & POLLOUT) { cf_callback_flags |= kCFSocketWriteCallBack; cf_option_flags |= kCFSocketAutomaticallyReenableWriteCallBack; } // Create a CFSocket as a runloop source for the toyfd file descriptor cf_context.info = toyfd; cfsocket = rwsched_tasklet_CFSocketCreateWithNative(toytask->rwsched_tasklet_info, kCFAllocatorSystemDefault, fd, cf_callback_flags, rwmsg_toysched_io_callback, &cf_context); RW_CF_TYPE_VALIDATE(cfsocket, rwsched_CFSocketRef); rwsched_tasklet_CFSocketSetSocketFlags(toytask->rwsched_tasklet_info, cfsocket, cf_option_flags); cfsource = rwsched_tasklet_CFSocketCreateRunLoopSource(toytask->rwsched_tasklet_info, kCFAllocatorSystemDefault, cfsocket, 0); RW_CF_TYPE_VALIDATE(cfsource, rwsched_CFRunLoopSourceRef); rwsched_tasklet_CFRunLoopAddSource(toytask->rwsched_tasklet_info, runloop, cfsource, instance->main_cfrunloop_mode); // Fill in the toyfd structure toyfd->cf_ref = cfsocket; toyfd->id = cfsocket->index; toyfd->fd = fd; toyfd->cb = cb; toyfd->ud = ud; toyfd->toytask = toytask; // Fill in the read context structure if (pollbits & POLLIN) { toyfd->read_context.source.cfsource = cfsource; } // Fill in the write context structure if (pollbits & POLLOUT) { toyfd->write_context.source.cfsource = cfsource; } // Return the callback id return (uint64_t) toyfd->id; }