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); }
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); } }
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; } }
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); }
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; }
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(); }
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; }
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; }
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); }
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? */ } }
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; }
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; }
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; }
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); } }
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; }
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; }
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 --; } }
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; }
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, ®h); 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; }
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(); }
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; }
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(); }
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); }
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; }
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); }
// 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; }
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; }
void rwmsg_destination_unset_noconndontq(rwmsg_destination_t *dt) { RW_ASSERT_TYPE(dt, rwmsg_destination_t); dt->noconndontq = 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); }
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; }