示例#1
0
void rwdts_appconf_prepare_complete_fail(rwdts_appconf_t *ac,
                                         const rwdts_xact_info_t *xact_info,
                                         rw_status_t rs,
                                         const char *errstr) {
  RW_ASSERT_TYPE(ac, rwdts_appconf_t);
  rwdts_appconf_xact_t *appx =
      (rwdts_appconf_xact_t *)xact_info->xact->group[ac->group->id]->scratch;
  RW_ASSERT_TYPE(appx, rwdts_appconf_xact_t);

  RW_ASSERT(appx->queries_in > 0);
  appx->queries_out++;
  RW_ASSERT(appx->queries_out <= appx->queries_in);

  int idx = appx->errs_ct++;
  appx->errs = realloc(appx->errs, sizeof(appx->errs[0]) * appx->errs_ct);
  appx->errs[idx].str = strdup(errstr);
  appx->errs[idx].rs = rs;
  appx->errs[idx].corrid = (xact_info->queryh &&
                            ((RWDtsQuery*)xact_info->queryh)->has_corrid ?
                            ((RWDtsQuery*)xact_info->queryh)->corrid : 0);

  rwdts_member_send_error(xact_info->xact, NULL,
                          (RWDtsQuery*)xact_info->queryh,
                          NULL, NULL, rs, errstr);
  RWTRACE_CRIT(xact_info->apih->rwtrace_instance,
               RWTRACE_CATEGORY_RWTASKLET,
               "APPCONF prepare_complete_fail code %d str '%s'\n",
               rs,
               errstr);

  rwdts_xact_info_respond_keyspec(xact_info, RWDTS_XACT_RSP_CODE_NACK,
                                  NULL, NULL);
}
示例#2
0
void rwdts_appconf_xact_add_issue(rwdts_appconf_t *ac,
                                  rwdts_xact_t *xact,
                                  rw_status_t rs,
                                  const char *errstr) {
  RW_ASSERT_TYPE(ac, rwdts_appconf_t);

  if (xact) {
    RW_ASSERT_TYPE(xact, rwdts_xact_t);

    rwdts_appconf_xact_t *appx =
        (rwdts_appconf_xact_t *)xact->group[ac->group->id]->scratch;
    RW_ASSERT_TYPE(appx, rwdts_appconf_xact_t);

    int idx = appx->errs_ct++;
    appx->errs = realloc(appx->errs, sizeof(appx->errs[0]) * appx->errs_ct);
    appx->errs[idx].str = strdup(errstr);
    appx->errs[idx].rs = rs;
    appx->errs[idx].corrid = 0;  //??

    // Send to error_report also
    rwdts_member_send_error(xact, NULL, NULL, ac->apih, NULL, rs, errstr);

  }
  else if (ac->group && ac->group->xact) {
    RW_ASSERT_TYPE(ac->group->xact, rwdts_xact_t);
    rwdts_member_send_error(ac->group->xact, NULL, NULL, ac->apih,
                            NULL, rs, errstr);
  }
  else {
    if (ac->apih) {
      RWTRACE_CRIT(ac->apih->rwtrace_instance,
                   RWTRACE_CATEGORY_RWTASKLET,
                   "%s: No xact, rs=%d, errstr=%s\n",
                   __FUNCTION__, rs, errstr);
    }
    else {
      DTS_PRINT("%s: No xact, rs=%d, errstr=%s\n",
                __FUNCTION__, rs, errstr);
    }
  }

  if (ac->apih) {
    RWTRACE_ERROR(ac->apih->rwtrace_instance,
                  RWTRACE_CATEGORY_RWTASKLET,
                  "APPCONF xact issue for group %d, rs %d, errstr '%s'\n",
                  ac->group->id,
                  rs,
                  errstr);
  }
  else {
    DTS_PRINT("APPCONF xact issue for group %d, rs %d, errstr '%s'\n",
              ac->group->id,
              rs,
              errstr);
  }
}
示例#3
0
void rwdts_appconf_register_deinit(rwdts_member_registration_t *reg) {
  if (reg->appconf) {
    if (reg->appconf->cb.prepare_dtor) {
      reg->appconf->cb.prepare_dtor(reg->appconf->cb.prepare_ud);
    }
    RW_ASSERT_TYPE(reg->appconf, rwdts_appconf_reg_t);
    RW_ASSERT_TYPE(reg->appconf->ac, rwdts_appconf_t);
    RW_FREE_TYPE(reg->appconf, rwdts_appconf_reg_t);
    reg->appconf = NULL;
  }
}
示例#4
0
void rwdts_appconf_prepare_complete_na(rwdts_appconf_t *ac,
                                       const rwdts_xact_info_t *xact_info) {
  RW_ASSERT_TYPE(ac, rwdts_appconf_t);
  rwdts_appconf_xact_t *appx = (rwdts_appconf_xact_t *)xact_info->xact->group[ac->group->id]->scratch;
  RW_ASSERT_TYPE(appx, rwdts_appconf_xact_t);

  RW_ASSERT(appx->queries_in > 0);
  appx->queries_out++;
  RW_ASSERT(appx->queries_out <= appx->queries_in);

  rwdts_xact_info_respond_keyspec(xact_info, RWDTS_XACT_RSP_CODE_NA, NULL, NULL);
}
示例#5
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;
}
示例#6
0
void
rwsched_dispatch_set_target_queue(rwsched_tasklet_ptr_t sched_tasklet,
                                  rwsched_dispatch_object_t object,
                                  rwsched_dispatch_queue_t queue)
{
#else
void
rwsched_dispatch_set_target_queue(rwsched_tasklet_ptr_t sched_tasklet,
                                  void *obj,
                                  rwsched_dispatch_queue_t queue)
{
  rwsched_dispatch_object_t object = (rwsched_dispatch_object_t) obj;
#endif
  // 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) {
    dispatch_set_target_queue(object._object->header.libdispatch_object._do,
			      queue->header.libdispatch_object._dq);
    return;
  }

  // Not yet implemented
  RW_CRASH();
}
示例#7
0
rwmsg_destination_t *rwmsg_destination_create(rwmsg_endpoint_t *ep,
        rwmsg_addrtype_t atype,
        const char *addrpath) {
    RW_ASSERT_TYPE(ep, rwmsg_endpoint_t);
    rwmsg_destination_t *dt = NULL;

    int plen = strlen(addrpath);
    if (plen >= RWMSG_PATH_MAX) {
        goto ret;
    }

    dt = (rwmsg_destination_t*)RW_MALLOC0_TYPE(sizeof(*dt), rwmsg_destination_t);
    dt->ep = ep;
    dt->refct = 1;

    RWMSG_EP_LOCK(ep);
    RW_DL_INSERT_HEAD(&ep->track.destinations, dt, trackelem);
    RWMSG_EP_UNLOCK(ep);
    ck_pr_inc_32(&ep->stat.objects.destinations);

    RW_ASSERT(atype == RWMSG_ADDRTYPE_UNICAST);
    dt->destination_ct=1;
    dt->atype = atype;
    strncpy(dt->apath, addrpath, sizeof(dt->apath));
    dt->apath[sizeof(dt->apath)-1]='\0';
    dt->apathhash = rw_hashlittle64(dt->apath, plen);

    dt->defstream.tx_win = 0;	/* never used without feedme cb */
    dt->defstream.defstream = TRUE;
    dt->defstream.refct = 1;
    dt->defstream.dest = dt;	/* no ref, this stream not destroyed in rwmsg_clichan.c */

ret:
    return dt;
}
示例#8
0
void rwmsg_destination_destroy(rwmsg_destination_t *dt) {
    RW_ASSERT_TYPE(dt, rwmsg_destination_t);
    if (!dt->refct) {
        rwmsg_endpoint_t *ep = dt->ep;
        RW_ASSERT(ep);

        //?? TBD rwmsg_endpoint_del_srvchan_method_binding(ep, sc, ...);

        RWMSG_EP_LOCK(ep);
        RW_DL_REMOVE(&ep->track.destinations, dt, trackelem);
        RWMSG_EP_UNLOCK(ep);
        ck_pr_dec_32(&ep->stat.objects.destinations);

        if (dt->localep) {
            rwmsg_endpoint_release(dt->localep);
            dt->localep = NULL;
        }

        if (dt->defstream.localsc) {
            _RWMSG_CH_DEBUG_(&dt->defstream.localsc->ch, "--");
            rwmsg_srvchan_release(dt->defstream.localsc);
            dt->defstream.localsc = NULL;
        }

        RW_FREE_TYPE(dt, rwmsg_destination_t);
        dt = NULL;
    }
    return;
}
示例#9
0
int
main(int argc, char *argv[])
{
  UNUSED(argc); UNUSED(argv);
  rwmsg_toysched_t toysched;
  rwmsg_toytask_t *toytask;
  toytimer_context_t toytimer_context;
  //uint64_t timer_id;

  // Create an instance of the toy scheduler
  rwmsg_toysched_init(&toysched);

  // Create a toytask
  toytask = rwmsg_toytask_create(&toysched);
  EXPECT_TRUE(toytask);

  // Allocate a callback context structure
  toytimer_context = (toytimer_context_t) RW_MALLOC0_TYPE(sizeof(*toytimer_context), toytimer_context_t);
  RW_ASSERT_TYPE(toytimer_context, toytimer_context_t);
  ud = toytimer_context;

  // Create the first oneshot toytimer
  toytimer_oneshot_create(loop, &g_timeout_watcher);
  
  // Run the toysched runloop until a specific number of timers are processed
  // rwmsg_toysched_runloop(&toysched, toytask, 1);
  int num_timers = 1 * 1000 * 100;
  while (1) {
    ev_run(loop, 0);
  }

  EXPECT_EQ(toytimer_context->timer_count, num_timers);
  printf("timer_count = %d\n", toytimer_context->timer_count);
}
示例#10
0
static void
rwdts_appconf_cb_reg_ready(rwdts_member_reg_handle_t  regh,
                           rw_status_t                reg_status,
                           void*                      ud)
{
  rwdts_appconf_t *ac = (rwdts_appconf_t *)ud;
  RW_ASSERT_TYPE(ac, rwdts_appconf_t);
  if (!((rwdts_member_registration_t *)regh)->appconf )
  {
    //printf("No appconf\n");
    return;
  }

  if (ac->reg_pend) {
    ac->reg_pend--;
  }
  /* Apply with xact=NULL to revert*/
  if (!ac->reg_pend && ac->phase_complete) {
    ac->cb.config_apply(ac->apih,
                      ac,
                      NULL, /* no xact -> original, committed data */
                      RWDTS_APPCONF_ACTION_INSTALL,
                      ac->cb.ctx,
                      NULL); /* no scratch? */
  }
}
示例#11
0
rw_status_t
rwdts_kv_update_db_xact_commit(rwdts_member_data_object_t *mobj, RWDtsQueryAction action)
{
  rwdts_api_t *apih;
  rwdts_member_registration_t *reg;

  reg = mobj->reg;
  RW_ASSERT_TYPE(reg, rwdts_member_registration_t);
  RW_ASSERT(action != RWDTS_QUERY_INVALID);
  apih = reg->apih;
  RW_ASSERT(apih);

  if (mobj->kv_tab_handle == NULL) {
    /* Problem */
    return RW_STATUS_FAILURE;
  }

  RWDTS_CREATE_SHARD(reg->reg_id, apih->client_path, apih->router_path);
  /* Perform KV xact operation */
  if (apih->db_up && ((action == RWDTS_QUERY_CREATE) ||
      (RWDTS_QUERY_UPDATE == action))) {
    rwdts_kv_light_api_xact_insert_commit(mobj->kv_tab_handle, mobj->serial_num,
                                          shard, (void *)mobj->key,
                                          mobj->key_len, (void *)rwdts_kv_light_insert_xact_commit_obj_cb,
                                          (void *)mobj);
  } else if (apih->db_up && (action == RWDTS_QUERY_DELETE)) {
    rwdts_kv_light_table_xact_delete_commit(mobj->kv_tab_handle, mobj->serial_num,
                                            (void *)mobj->key,
                                            mobj->key_len,
                                            (void *)rwdts_kv_light_delete_xact_commit_obj_cb,
                                            (void *)mobj);
  }
  return RW_STATUS_SUCCESS;
}
示例#12
0
rwsched_dispatch_queue_t
rwsched_dispatch_get_main_queue(rwsched_instance_ptr_t instance)
{
  RW_CF_TYPE_VALIDATE(instance, rwsched_instance_ptr_t);
  RW_ASSERT_TYPE(instance->main_rwqueue, rwsched_dispatch_queue_t);
  return instance->main_rwqueue;
}
示例#13
0
static void rwdts_appconf_regn_check_timer(void *ctx)
{
  rwdts_appconf_t *ac = (rwdts_appconf_t *)ctx;
  RW_ASSERT_TYPE(ac, rwdts_appconf_t);
  rwdts_api_t* apih = ac->apih;
  RW_ASSERT_TYPE(apih, rwdts_api_t);

  RW_ASSERT_MESSAGE(ac->phase_complete, "Appconf Registration not complete on time");

  rwsched_dispatch_source_cancel(apih->tasklet,
                                 ac->regn_timer);
  rwsched_dispatch_release(apih->tasklet,
                           ac->regn_timer);
  ac->regn_timer = NULL;

  return;
}
示例#14
0
void rwmsg_destination_release(rwmsg_destination_t *dt) {
    RW_ASSERT_TYPE(dt, rwmsg_destination_t);
    bool zero=0;
    ck_pr_dec_32_zero(&dt->refct, &zero);
    if (zero) {
        rwmsg_garbage(&dt->ep->gc, RWMSG_OBJTYPE_DESTINATION, dt, NULL, NULL);
    }
}
示例#15
0
rwsched_dispatch_queue_t
rwsched_dispatch_get_default_queue(rwsched_tasklet_ptr_t sched_tasklet)
{
  // 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(instance->default_rwqueue, rwsched_dispatch_queue_t);
  return instance->default_rwqueue;
}
示例#16
0
static void *rwdts_appconf_xact_init(rwdts_group_t *grp,
                                     rwdts_xact_t *xact,
                                     void *ctx) {
  RW_ASSERT_TYPE(xact, rwdts_xact_t);
  rwdts_appconf_t *ac = (rwdts_appconf_t *)ctx;
  RW_ASSERT_TYPE(ac, rwdts_appconf_t);

  rwdts_appconf_xact_t *appx = NULL;

  appx = RW_MALLOC0_TYPE(sizeof(*appx), rwdts_appconf_xact_t);
  appx->ac = ac;
  if (ac->cb.xact_init) {
    if (ac->cb.xact_init_dtor) {
      appx->scratch_gi = ac->cb.xact_init_gi(ac, xact, ac->cb.ctx);
    } else {
      appx->scratch = ac->cb.xact_init(ac, xact, ac->cb.ctx);
    }
  }

  return appx;
}
示例#17
0
void rwmsg_destination_feedme_callback(rwmsg_destination_t *dest,
                                       rwmsg_closure_t *cb) {
    RW_ASSERT_TYPE(dest, rwmsg_destination_t);
    if (cb) {
        memcpy(&dest->defstream.cb, cb, sizeof(dest->defstream.cb));
        int defwin = 1;
        rwmsg_endpoint_get_property_int(dest->ep, "/rwmsg/destination/defwin", &defwin);
        dest->defstream.tx_win = defwin;
        dest->feedme_count ++;
    } else {
        memset(&dest->defstream.cb, 0, sizeof(dest->defstream.cb));
        dest->defstream.tx_win = 0;	/* never be used without feedme cb */
        dest->feedme_count --;
    }
}
示例#18
0
static void rwdts_appconf_xact_deinit(rwdts_group_t *grp,
                                      rwdts_xact_t *xact,
                                      void *ctx,
                                      void *scratch) {
  rwdts_appconf_xact_t *appx = (rwdts_appconf_xact_t *)scratch;
  RW_ASSERT_TYPE(appx, rwdts_appconf_xact_t);
  rwdts_appconf_t *ac = appx->ac;
  int k;

  if (ac->cb.xact_deinit) {
    if (ac->cb.xact_deinit_dtor) {
      ac->cb.xact_deinit_gi(ac,
                            xact,
                            ac->cb.ctx,
                            appx->scratch_gi);
      if (appx->scratch_gi) {
        g_value_unset(appx->scratch_gi);
        appx->scratch_gi = NULL;
      }
    } else {
      ac->cb.xact_deinit(ac,
                         xact,
                         ac->cb.ctx,
                         appx->scratch);
      appx->scratch = NULL;
    }
  } else {
    if (ac->cb.xact_init_dtor) {
      if (appx->scratch_gi) {
        g_value_unset(appx->scratch_gi);
        appx->scratch_gi = NULL;
      }
    } else {
      RW_ASSERT(!appx->scratch);
    }
  }
  for(k=0;k<appx->errs_ct;free(appx->errs[k].str),k++);
  free(appx->errs);
  appx->errs = NULL;
  appx->errs_ct = 0;
  RW_FREE_TYPE(appx, rwdts_appconf_xact_t);
  appx = NULL;
}
示例#19
0
static rwdts_member_reg_handle_t rwdts_appconf_register_int(rwdts_appconf_t *ac,
                                                            const rw_keyspec_path_t *ks,
                                                            rwdts_shard_info_detail_t *shard,
                                                            const ProtobufCMessageDescriptor *pbdesc,
                                                            uint32_t flags,
                                                            rwdts_appconf_prepare_cb_t prepare_cb,
                                                            void *prepare_ud,
                                                            GDestroyNotify prepare_cb_dtor) {
  RW_ASSERT(ac);
  if (!ac) {
    return NULL;
  }
  RW_ASSERT_TYPE(ac, rwdts_appconf_t);

  rwdts_member_reg_handle_t regh = NULL;

  RwSchemaCategory category = rw_keyspec_path_get_category((rw_keyspec_path_t*)ks);

  if (category != RW_SCHEMA_CATEGORY_CONFIG) {
    return NULL;
  }

  flags &= (~RWDTS_FLAG_PUBLISHER);
  flags |= RWDTS_FLAG_SUBSCRIBER;
  flags |= RWDTS_FLAG_CACHE;

  rwdts_group_register_keyspec(ac->group, ks,
        rwdts_appconf_cb_reg_ready, rwdts_appconf_cb_prepare,
        NULL, NULL, NULL, flags, ac, &regh);
  if (regh) {
    rwdts_member_registration_t *reg = (rwdts_member_registration_t*)regh;

    rwdts_appconf_reg_t *appr = RW_MALLOC0_TYPE(sizeof(*appr), rwdts_appconf_reg_t);
    reg->appconf = appr;
    appr->ac = ac;
    appr->cb.prepare = prepare_cb; /* may be NULL! */
    appr->cb.prepare_ud = prepare_ud;
    appr->cb.prepare_dtor = prepare_cb_dtor;
  }
  ac->reg_pend++;
  return regh;
}
示例#20
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();
}
示例#21
0
rwsched_dispatch_queue_t
rwsched_dispatch_get_global_queue(rwsched_tasklet_ptr_t sched_tasklet,
				  long priority) {
  // 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(priority >= DISPATCH_QUEUE_PRIORITY_BACKGROUND);
  RW_ASSERT(priority <= DISPATCH_QUEUE_PRIORITY_HIGH);
  int i=0;
  for (i=0; i<RWSCHED_DISPATCH_QUEUE_GLOBAL_CT; i++) {
    if (instance->global_rwqueue[i].pri == priority) {
      RW_ASSERT_TYPE(instance->global_rwqueue[i].rwq, rwsched_dispatch_queue_t);
      return instance->global_rwqueue[i].rwq;
    }
  }
  RW_CRASH();
  return NULL;
}
示例#22
0
void
rwsched_dispatch_sync_f(rwsched_tasklet_ptr_t sched_tasklet,
                        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) {
    dispatch_sync_f(queue->header.libdispatch_object._dq, context, handler);
    return;
  }

  // Not yet implemented
  RW_CRASH();
}
示例#23
0
void rwdts_appconf_group_destroy(rwdts_appconf_t *ac) {
  RW_ASSERT_TYPE(ac, rwdts_appconf_t);
  if (ac->cb.xact_init_dtor) {
    ac->cb.xact_init_dtor(ac->cb.ctx);
  }
  if (ac->cb.xact_deinit_dtor) {
    ac->cb.xact_deinit_dtor(NULL);
  }

  if (ac->regn_timer) {
    rwsched_dispatch_source_cancel(ac->apih->tasklet,
                                   ac->regn_timer);
    rwsched_dispatch_release(ac->apih->tasklet,
                             ac->regn_timer);
    ac->regn_timer = NULL;
  }

  memset(&ac->cb, 0, sizeof(ac->cb));
  rwdts_group_destroy(ac->group);
  RW_FREE_TYPE(ac, rwdts_appconf_t);
}
示例#24
0
static void
rwsched_dispatch_intercept(void *ud)
{
  rwsched_dispatch_what_ptr_t what = ud;

  // Validate input paraemters
  RW_ASSERT_TYPE(what, rwsched_dispatch_what_ptr_t);
  RW_ASSERT(what->closure.handler);
  rwsched_tasklet_ptr_t sched_tasklet = what->tasklet_info;
  RW_CF_TYPE_VALIDATE(sched_tasklet, rwsched_tasklet_ptr_t);

  g_rwresource_track_handle = sched_tasklet->rwresource_track_handle;
  g_tasklet_info = sched_tasklet;

  (what->closure.handler)(what->closure.context);

  RW_FREE_TYPE(what, rwsched_dispatch_what_ptr_t);
  rwsched_tasklet_unref(sched_tasklet);

  g_tasklet_info = 0;
  g_rwresource_track_handle = 0;
}
示例#25
0
static void
toytimer_oneshot_callback(EV_P_ ev_timer *w, int revents)
{
  UNUSED(w); UNUSED(revents);
  toytimer_context_t toytimer_context = (toytimer_context_t) ud;

  printf("timer %d\n", toytimer_context->timer_count);

  // Validate input parameters
  RW_ASSERT_TYPE(toytimer_context, toytimer_context_t);

  // Validate the toytimer context parameters and update them
  EXPECT_EQ(toytimer_context->type, TOYTIMER_TYPE_ONESHOT);
  toytimer_context->timer_count++;

  // Stop this timer from running
  // This causes the inntermost ev_run to stop iterating
  ev_break(EV_A_ EVBREAK_ONE);

  // Create another oneshot toytimer
  toytimer_oneshot_create(loop, &g_timeout_watcher);
}
示例#26
0
// This will be supported after sharding support
//
//LCOV_EXCL_START
rw_status_t
rwdts_kv_update_db_xact_precommit(rwdts_member_data_object_t *mobj, RWDtsQueryAction action)
{
  rwdts_api_t *apih;
  rwdts_member_registration_t *reg;
  ProtobufCMessage *msg;
  uint8_t *payload;
  size_t  payload_len;
  rw_status_t status;
  rwdts_kv_table_handle_t *kv_tab_handle = NULL;
  rwdts_shard_info_detail_t *shard_key1;
  uint8_t *local_ks_binpath = NULL;
  size_t local_ks_binpath_len;
  rw_keyspec_path_t *local_keyspec = NULL;
  /* Build the shard-key to get the shard-id and DB number */
  char str[15] = "banana";

  reg = mobj->reg;
  RW_ASSERT_TYPE(reg, rwdts_member_registration_t);
  apih = reg->apih;
  RW_ASSERT(apih);
  RW_ASSERT(action != RWDTS_QUERY_INVALID);
  msg = mobj->msg;

  shard_key1 = RW_MALLOC0_TYPE(sizeof(rwdts_shard_info_detail_t), rwdts_shard_info_detail_t);
  shard_key1->shard_key_detail.u.byte_key.k.key = (void *)RW_MALLOC(sizeof(str));
  memcpy((char *)shard_key1->shard_key_detail.u.byte_key.k.key, &str[0], strlen(str));
  shard_key1->shard_key_detail.u.byte_key.k.key_len = strlen(str);

  /* Get the shard-id and DB number */
  rwdts_shard_db_num_info_t *shard_db_num_info = RW_MALLOC0(sizeof(rwdts_shard_db_num_info_t));

  status = rw_keyspec_path_create_dup(reg->keyspec, &apih->ksi , &local_keyspec);
  RW_ASSERT(status == RW_STATUS_SUCCESS);

  status = rw_keyspec_path_get_binpath(local_keyspec, &apih->ksi , (const uint8_t **)&local_ks_binpath, &local_ks_binpath_len);
  RW_ASSERT(status == RW_STATUS_SUCCESS);
  rwdts_member_get_shard_db_info_keyspec(apih, local_keyspec,
                                         shard_key1,
                                         shard_db_num_info);
  if (shard_db_num_info->shard_db_num_cnt > 0) {
    mobj->db_number = shard_db_num_info->shard_db_num[0].db_number;
    mobj->shard_id = shard_db_num_info->shard_db_num[0].shard_chunk_id;
    /* Search for KV table handle */
    status = RW_SKLIST_LOOKUP_BY_KEY(&(apih->kv_table_handle_list), &mobj->db_number,
                                     (void *)&kv_tab_handle);
    if (!kv_tab_handle) {
      kv_tab_handle = rwdts_kv_light_register_table(apih->handle, mobj->db_number);
      RW_ASSERT(kv_tab_handle);
      status = RW_SKLIST_INSERT(&(apih->kv_table_handle_list), kv_tab_handle);
      RW_ASSERT(status == RW_STATUS_SUCCESS);
    }
    mobj->kv_tab_handle = kv_tab_handle;
    RWDTS_CREATE_SHARD(reg->reg_id, apih->client_path, apih->router_path);
    /* Perform KV xact operation */
    if (apih->db_up && ((action == RWDTS_QUERY_CREATE) ||
        (RWDTS_QUERY_UPDATE == action))) {
      RW_ASSERT(msg);
      payload = protobuf_c_message_serialize(NULL, msg, &payload_len);
      rwdts_kv_light_table_xact_insert(kv_tab_handle, 0, shard,
                                       (void *)mobj->key,
                                       mobj->key_len,
                                       payload,
                                       payload_len,
                                       (void *)rwdts_kv_light_insert_xact_obj_cb,
                                       (void *)mobj);
    } else if (apih->db_up && (action == RWDTS_QUERY_DELETE)) {
       rwdts_kv_light_table_xact_delete(kv_tab_handle, 0,
                                        (void *)mobj->key,
                                        mobj->key_len,
                                        (void *)rwdts_kv_light_delete_xact_obj_cb,
                                        (void *)mobj);
    }
  }
  if (shard_db_num_info->shard_db_num_cnt) {
    free(shard_db_num_info->shard_db_num);
  }
  RW_FREE(shard_db_num_info);
  rw_keyspec_path_free(local_keyspec, NULL);
  RW_FREE(shard_key1->shard_key_detail.u.byte_key.k.key);
  RW_FREE_TYPE(shard_key1, rwdts_shard_info_detail_t);
  return RW_STATUS_SUCCESS;
}
示例#27
0
static rwdts_member_rsp_code_t
rwdts_appconf_cb_prepare(const rwdts_xact_info_t *xact_info,
                         RWDtsQueryAction action,
                         const rw_keyspec_path_t *keyspec,
                         const ProtobufCMessage *msg,
                         void* user_data)
{
  RW_ASSERT(xact_info);
  if (xact_info == NULL) {
    return RWDTS_ACTION_NOT_OK;
  }
  rwdts_xact_t *xact = xact_info->xact;
  RW_ASSERT_TYPE(xact, rwdts_xact_t);
  RW_ASSERT(action != RWDTS_QUERY_INVALID);

  rwdts_appconf_xact_t *appx = (rwdts_appconf_xact_t *)xact_info->scratch;
  RW_ASSERT_TYPE(appx, rwdts_appconf_xact_t);
  rwdts_appconf_t *ac = appx->ac;
  RW_ASSERT_TYPE(ac, rwdts_appconf_t);

  rwdts_member_registration_t* reg = (rwdts_member_registration_t *)xact_info->regh;
  if (reg->appconf->cb.prepare) {
    /* This is a temporary code to avoid system blow-up. This code will
       be removed once pb-delta is available */
    if (action == RWDTS_QUERY_DELETE) {
      if (!(reg->flags & RWDTS_FLAG_DELTA_READY)) {
        appx->queries_in++;
        rwdts_appconf_prepare_complete_ok(reg->appconf->ac, xact_info);
        return RWDTS_ACTION_NOT_OK;
      }
      RW_ASSERT(!msg);
      msg = rw_keyspec_path_create_delete_delta(keyspec, &xact->ksi,
                                                reg->keyspec);
      if (!msg) {
        size_t depth_d = rw_keyspec_path_get_depth(keyspec);
        size_t depth_r = rw_keyspec_path_get_depth(reg->keyspec);
        if ((depth_d <= depth_r) && (reg->flags & RWDTS_FLAG_DELTA_READY)) {   
          return rwdts_appconf_find_keys_call_prepare(reg, keyspec, xact_info);
        } else {
          appx->queries_in++;
          rwdts_appconf_prepare_complete_ok(reg->appconf->ac, xact_info);
          return RWDTS_ACTION_NOT_OK;
        }
      }
      RW_ASSERT(msg);
    }
    appx->queries_in++;
    if (reg->appconf->cb.prepare_dtor) {
      /* Take a ref (make a copy, really) for Gi callers, who may ref
         to keep it, and will unref when returning from the prepare
         callback */
      xact_info = rwdts_xact_info_ref((rwdts_xact_info_t*)xact_info);
      rw_keyspec_path_t *local_ks = NULL;
      rw_status_t rs = rw_keyspec_path_create_dup((rw_keyspec_path_t*)keyspec, &xact_info->xact->ksi,&local_ks);
      if (rs != RW_STATUS_SUCCESS) {
        rwdts_appconf_prepare_complete_ok(reg->appconf->ac, xact_info);
        if (msg && (action == RWDTS_QUERY_DELETE)) {
          protobuf_c_message_free_unpacked(NULL, (ProtobufCMessage*)msg);
          msg = NULL;
        }
        return RWDTS_ACTION_NOT_OK;
      }
      reg->appconf->cb.prepare_gi(xact_info->apih,
                                  reg->appconf->ac,
                                  xact,
                                  xact_info,
                                  local_ks,
                                  msg,
                                  ac->cb.ctx,
                                  appx->scratch,
                                  reg->appconf->cb.prepare_ud);
    } else {
      reg->appconf->cb.prepare(xact_info->apih,
                               reg->appconf->ac,
                               xact,
                               xact_info,
                               (rw_keyspec_path_t*)keyspec,
                               msg,
                               ac->cb.ctx,
                               appx->scratch);
    }
  } else {
    appx->queries_in++;
    rwdts_appconf_prepare_complete_ok(reg->appconf->ac, xact_info);
  }
  if (msg && (action == RWDTS_QUERY_DELETE)) {
     protobuf_c_message_free_unpacked(NULL, (ProtobufCMessage *)msg);
     msg = NULL;
  }
  return RWDTS_ACTION_ASYNC;
}
示例#28
0
void rwmsg_destination_unset_noconndontq(rwmsg_destination_t *dt) {
    RW_ASSERT_TYPE(dt, rwmsg_destination_t);
    dt->noconndontq = 0;
}
示例#29
0
/*
 * appconf register xpath
 */
rw_status_t
rwdts_appconf_register_xpath_gi(rwdts_appconf_t*                  ac,
                                const char*                       xpath,
                                uint32_t                          flags,
                                rwdts_appconf_prepare_cb_gi        prepare,
                                void *prepare_ud,
                                GDestroyNotify prepare_dtor,
                                rwdts_member_reg_handle_t*        handle)
{
  rw_status_t rs;
  rw_keyspec_path_t *keyspec = NULL;
  const rw_yang_pb_schema_t* schema = NULL;
  rwdts_api_t *apih;

  RW_ASSERT_TYPE(ac, rwdts_appconf_t);
  apih = ac->apih;
  RW_ASSERT_TYPE(apih, rwdts_api_t);

  /* Find the schema  */
  schema = rwdts_api_get_ypbc_schema(apih);

  if (!schema) {
    RWTRACE_CRIT(apih->rwtrace_instance,
                 RWTRACE_CATEGORY_RWTASKLET,
                 "register_xpath[%s] failed - Schema is NULL", xpath);
    return(RW_STATUS_SUCCESS);
  }

  /* Create keyspec from xpath */
  keyspec  = rw_keyspec_path_from_xpath(schema, (char*)xpath, RW_XPATH_KEYSPEC, &apih->ksi);
  if (!keyspec) {
    RWTRACE_CRIT(apih->rwtrace_instance,
                 RWTRACE_CATEGORY_RWTASKLET,
                 "keyspec from xpath failed for xpath[%s]", xpath);
    return (RW_STATUS_FAILURE);
  }

  RW_ASSERT(keyspec != NULL);

  RwSchemaCategory cat = rw_keyspec_path_get_category(keyspec);

  if (cat == RW_SCHEMA_CATEGORY_ANY) {
    rw_keyspec_path_set_category(keyspec, NULL, RW_SCHEMA_CATEGORY_CONFIG);
    cat = RW_SCHEMA_CATEGORY_CONFIG;
  }
  if (cat != RW_SCHEMA_CATEGORY_CONFIG) {
      RWTRACE_CRIT(apih->rwtrace_instance,
                 RWTRACE_CATEGORY_RWTASKLET,
                 "keyspec with wrong category xpath[%s]", xpath);
      RW_ASSERT_MESSAGE(0,"%s:Wrong xpath in appconf register %s", apih->client_path, xpath);
      return (RW_STATUS_FAILURE);
  }
  rs =  rwdts_appconf_register_keyspec_gi(ac,
                                          keyspec,
                                          flags,
                                          prepare,
                                          prepare_ud,
                                          prepare_dtor,
                                          handle);

  rw_keyspec_path_free(keyspec, NULL);

  return(rs);
}
示例#30
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;
}