Example #1
0
rwsched_dispatch_queue_t
rwsched_dispatch_queue_create(rwsched_tasklet_ptr_t sched_tasklet,
                              const char *label,
                              dispatch_queue_attr_t attr)
{
  struct rwsched_dispatch_queue_s *queue;

  // Validate input paraemters
  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);

  // Allocate memory for the dispatch queue
  queue = (rwsched_dispatch_queue_t) RW_MALLOC0_TYPE(sizeof(*queue), rwsched_dispatch_queue_t);
  RW_ASSERT_TYPE(queue, rwsched_dispatch_queue_t);

  // If libdispatch is enabled for the entire instance, then call the libdispatch routine
  if (instance->use_libdispatch_only) {
    queue->header.libdispatch_object._dq = dispatch_queue_create(label, attr);
    RW_ASSERT(queue->header.libdispatch_object._dq);

    rwsched_tasklet_ref(sched_tasklet);
    ck_pr_inc_32(&sched_tasklet->counters.queues);

    return queue;
  }

  // Not yet implemented
  RW_CRASH();
  return NULL;
}
Example #2
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;
}
Example #3
0
void
rwsched_dispatch_after_f(rwsched_tasklet_ptr_t sched_tasklet,
                         dispatch_time_t when,
                         rwsched_dispatch_queue_t queue,
                         void *context,
                         dispatch_function_t handler)
{
  // Validate input paraemters
  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);
  RW_ASSERT_TYPE(queue, rwsched_dispatch_queue_t);

  // If libdispatch is enabled for the entire instance, then call the libdispatch routine
  if (instance->use_libdispatch_only) {
    RW_ASSERT(queue->header.libdispatch_object._dq);
    if (queue == instance->main_rwqueue &&
        sched_tasklet->blocking_mode.blocked) {
      //RW_CRASH();
      rwsched_dispatch_what_ptr_t what = (rwsched_dispatch_what_ptr_t) RW_MALLOC0_TYPE(sizeof(*what), rwsched_dispatch_what_ptr_t); /* always leaked! */
      what->type = RWSCHED_DISPATCH_ASYNC;
      what->closure.handler = handler;
      what->closure.context = context;
      what->queue = queue;
      g_array_append_val(sched_tasklet->dispatch_what_array, what);
    }
    else {
      rwsched_dispatch_what_ptr_t what = (rwsched_dispatch_what_ptr_t) RW_MALLOC0_TYPE(sizeof(*what), rwsched_dispatch_what_ptr_t);
      what->type = RWSCHED_DISPATCH_ASYNC;
      what->closure.handler = handler;
      what->closure.context = context;
      what->queue = queue;
      rwsched_tasklet_ref(sched_tasklet);
      what->tasklet_info = sched_tasklet;
      dispatch_after_f(when, queue->header.libdispatch_object._dq, (void*)what, rwsched_dispatch_intercept);
    }
    return;
  }

  // Not yet implemented
  RW_CRASH();
}
Example #4
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;
}