コード例 #1
0
rwsched_tasklet_t *
rwsched_tasklet_new(rwsched_instance_t *instance)
{
  rwsched_tasklet_ptr_t sched_tasklet;
  //int i;

  // Validate input paraemters
  RW_CF_TYPE_VALIDATE(instance, rwsched_instance_ptr_t);

  // Allocate memory for the new sched_tasklet sched_tasklet structure and track it
  sched_tasklet = RW_CF_TYPE_MALLOC0(sizeof(*sched_tasklet), rwsched_tasklet_ptr_t);
  RW_CF_TYPE_VALIDATE(sched_tasklet, rwsched_tasklet_ptr_t);

  rwsched_instance_ref(instance);
  sched_tasklet->instance = instance;
  sched_tasklet->rwresource_track_handle = RW_RESOURCE_TRACK_CREATE_CONTEXT("Tasklet Context");

  // Look for an unused entry in tasklet_array (start the indexes at 1 for now)
  int i; for (i = 1 ; i < instance->tasklet_array->len ; i++) {
    if (g_array_index(instance->tasklet_array, rwsched_tasklet_ptr_t, i) == NULL) {
      g_array_index(instance->tasklet_array, rwsched_tasklet_ptr_t, i) = sched_tasklet;
      break;
    }
  }
  if (i >= instance->tasklet_array->len) {
    // Insert a new element at the end of the array
    g_array_append_val(instance->tasklet_array, sched_tasklet);
  }


#ifdef _CF_
  // Allocate an array of cftimer pointers and track it
  rwsched_CFRunLoopTimerRef cftimer = NULL;
  sched_tasklet->cftimer_array = g_array_sized_new(TRUE, TRUE, sizeof(void *), 256);
  g_array_append_val(sched_tasklet->cftimer_array, cftimer);

  // Allocate an array of cfsocket pointers and track it
  rwsched_CFSocketRef cfsocket = NULL;
  sched_tasklet->cfsocket_array = g_array_sized_new(TRUE, TRUE, sizeof(void *), 256);
  g_array_append_val(sched_tasklet->cfsocket_array, cfsocket);

  // Allocate an array of cfsocket pointers and track it
  rwsched_CFRunLoopSourceRef cfsource = NULL;
  sched_tasklet->cfsource_array = g_array_sized_new(TRUE, TRUE, sizeof(void *), 256);
  g_array_append_val(sched_tasklet->cfsource_array, cfsource);

  // Allocate an array of dispatch_what pointers and track it
  rwsched_dispatch_what_ptr_t dispatch_what = NULL;
  sched_tasklet->dispatch_what_array = g_array_sized_new(TRUE, TRUE, sizeof(void *), 256);
  g_array_append_val(sched_tasklet->dispatch_what_array, dispatch_what);
#endif

  rwsched_tasklet_ref(sched_tasklet);
  ck_pr_inc_32(&g_rwsched_tasklet_count);

  // Return the allocated sched_tasklet sched_tasklet structure
  return sched_tasklet;
}
コード例 #2
0
CF_EXPORT rwsched_CFRunLoopTimerRef
rwsched_tasklet_CFRunLoopTimerCreate(rwsched_tasklet_ptr_t sched_tasklet,
                                     CFAllocatorRef allocator,
                                     CFAbsoluteTime fireDate,
                                     CFTimeInterval interval,
                                     CFOptionFlags flags,
                                     CFIndex order,
                                     rwsched_CFRunLoopTimerCallBack callout,
                                     rwsched_CFRunLoopTimerContext *context)
{
    // Validate input parameters
    RW_CF_TYPE_VALIDATE(sched_tasklet, rwsched_tasklet_ptr_t);
    rwsched_instance_ptr_t instance = sched_tasklet->instance;
    RW_CF_TYPE_VALIDATE(instance, rwsched_instance_ptr_t);

    rwsched_CFRunLoopTimerRef rwsched_timer;
    unsigned int i;

    RW_ASSERT(context->info);

    // Allocate a rwsched container type and track it
    rwsched_timer = RW_CF_TYPE_MALLOC0(sizeof(*rwsched_timer), rwsched_CFRunLoopTimerRef);

    // Look for an unused entry in cftimer_array (start the indexes at 1 for now)
    //RW_GOBJECT_TYPE_VALIDATE(sched_tasklet->cftimer_array, GArray);
    for (i = 1 ; i < sched_tasklet->cftimer_array->len ; i++) {
        if (g_array_index(sched_tasklet->cftimer_array, rwsched_CFRunLoopTimerRef, i) == NULL) {
            g_array_index(sched_tasklet->cftimer_array, rwsched_CFRunLoopTimerRef, i) = rwsched_timer;
            break;
        }
    }
    if (i >= sched_tasklet->cftimer_array->len) {
        // Insert a new element at the end of the array
        g_array_append_val(sched_tasklet->cftimer_array, rwsched_timer);
    }

    // Mark the rwsched_timer as in use
    RW_CF_TYPE_VALIDATE(rwsched_timer, rwsched_CFRunLoopTimerRef);
    rwsched_timer->index = i;

    if (interval == 0) {
        rwsched_timer->onetime_timer = 1;
        rwsched_timer->ott.allocator = allocator;
        rwsched_timer->ott.flags = flags;
        rwsched_timer->ott.order = order;
    }

    // Call the native CFRunLoop function
    if (context && context->info == NULL) {
        context->info = rwsched_timer;
    }
    rwsched_timer->tmp_context = *context;
    rwsched_timer->tmp_context.info = rwsched_timer;
    rwsched_timer->cf_callout = callout;
    rwsched_tasklet_ref(sched_tasklet);
    rwsched_timer->callback_context.tasklet_info = sched_tasklet;
    rwsched_instance_ref(instance);
    rwsched_timer->callback_context.instance = instance;
    rwsched_timer->cf_object = CFRunLoopTimerCreate(allocator,
                               fireDate,
                               interval,
                               flags,
                               order,
                               rwsched_cftimer_callout_intercept,
                               &rwsched_timer->tmp_context);
    rwsched_timer->cf_context = *context;

    // Return the rwsched container type
    return rwsched_timer;
}
コード例 #3
0
rwsched_instance_t *
rwsched_instance_new(void)
{
  struct rwsched_instance_s *instance;

  // Allocate memory for the new instance

  // Register the rwsched instance types
  RW_CF_TYPE_REGISTER(rwsched_instance_ptr_t);
  RW_CF_TYPE_REGISTER(rwsched_tasklet_ptr_t);
  rwsched_CFRunLoopInit();
  rwsched_CFSocketInit();

  // Allocate the Master Resource-Tracking Handle
  g_rwresource_track_handle = RW_RESOURCE_TRACK_CREATE_CONTEXT("The Master Context");

  // Allocate a rwsched instance type and track it
  instance = RW_CF_TYPE_MALLOC0(sizeof(*instance), rwsched_instance_ptr_t);
  RW_CF_TYPE_VALIDATE(instance, rwsched_instance_ptr_t);

  // Set the instance configuration
  instance->config.single_thread = TRUE;

  // For now use libdispatch only
  instance->use_libdispatch_only = TRUE;
  // libdispatch_init();

  // Fake up a rwqueue placeholder object to use as the (NULL) DISPATCH_TARGET_QUEUE_DEFAULT
  RW_ASSERT(instance->use_libdispatch_only);
  instance->default_rwqueue = (rwsched_dispatch_queue_t) RW_MALLOC0_TYPE(sizeof(*instance->default_rwqueue), rwsched_dispatch_queue_t);
  RW_ASSERT_TYPE(instance->default_rwqueue, rwsched_dispatch_queue_t);
  instance->default_rwqueue->header.libdispatch_object._dq = DISPATCH_TARGET_QUEUE_DEFAULT;

  // Fake up a rwqueue placeholder object to use as DISPATCH_TARGET_QUEUE_MAIN
  RW_ASSERT(instance->use_libdispatch_only);
  instance->main_rwqueue = (rwsched_dispatch_queue_t) RW_MALLOC0_TYPE(sizeof(*instance->main_rwqueue), rwsched_dispatch_queue_t);
  RW_ASSERT_TYPE(instance->main_rwqueue, rwsched_dispatch_queue_t);
  instance->main_rwqueue->header.libdispatch_object._dq = dispatch_get_main_queue();

  // Fake up rwqueue placeholder objects for the usual four global
  // queues.  The pri values are not 0,1,2,3 or similar, they are
  // -MAX, -2, 0, 2.  We do not support arbitrary pri values, although
  // I think the dispatch API is intended to.
  RW_ASSERT(instance->use_libdispatch_only);
  RW_STATIC_ASSERT(RWSCHED_DISPATCH_QUEUE_GLOBAL_CT == 4);
  static long pris[RWSCHED_DISPATCH_QUEUE_GLOBAL_CT] = {
    DISPATCH_QUEUE_PRIORITY_HIGH,
    DISPATCH_QUEUE_PRIORITY_DEFAULT,
    DISPATCH_QUEUE_PRIORITY_LOW,
    DISPATCH_QUEUE_PRIORITY_BACKGROUND
  };
  int  i; for (i=0; i<RWSCHED_DISPATCH_QUEUE_GLOBAL_CT; i++) {
    instance->global_rwqueue[i].pri = pris[i];
    instance->global_rwqueue[i].rwq = (rwsched_dispatch_queue_t) RW_MALLOC0_TYPE(sizeof(*instance->global_rwqueue[i].rwq), rwsched_dispatch_queue_t);
    RW_ASSERT_TYPE(instance->global_rwqueue[i].rwq, rwsched_dispatch_queue_t);
    instance->global_rwqueue[i].rwq->header.libdispatch_object._dq = dispatch_get_global_queue(pris[i], 0);
    RW_ASSERT(instance->global_rwqueue[i].rwq->header.libdispatch_object._dq);
  }

  instance->main_cfrunloop_mode = kCFRunLoopDefaultMode;
  //instance->main_cfrunloop_mode = CFSTR("TimerMode");
  //instance->deferred_cfrunloop_mode = CFSTR("Deferred Mode");

  // Allocate an array of tasklet pointers and track it
  rwsched_tasklet_t *tasklet = NULL;
  instance->tasklet_array = g_array_sized_new(TRUE, TRUE, sizeof(void *), 256);
  g_array_append_val(instance->tasklet_array, tasklet);

  rwsched_instance_ref(instance);
  ck_pr_inc_32(&g_rwsched_instance_count);
  //RW_ASSERT(g_rwsched_instance_count <= 2);
  g_rwsched_instance = instance;

  instance->rwlog_instance = rwlog_init("RW.Sched");

  // Return the instance pointer
  return instance;
}