Пример #1
0
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);
}
Пример #2
0
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;
}