rwmsg_method_t *rwmsg_method_create(rwmsg_endpoint_t *ep, const char *path, rwmsg_signature_t *sig, rwmsg_closure_t *requestcb) { RW_ASSERT(path); RW_ASSERT(sig); rwmsg_method_t *meth = NULL; uint64_t pathhash = 0; int32_t pathidx = 0; if (requestcb) { pathidx = rwmsg_endpoint_path_add(ep, path, &pathhash); } else { pathhash = rwmsg_endpoint_path_hash(ep, path); } RW_ASSERT(pathhash); if (pathidx || !requestcb/*null cb in broker, ignore other tasklet's entries for small model broker */) { meth = (rwmsg_method_t*)RW_MALLOC0_TYPE(sizeof(*meth), rwmsg_method_t); meth->pathidx = pathidx; meth->pathhash = pathhash; strncpy(meth->path, path, sizeof(meth->path)); meth->path[sizeof(meth->path)-1] = '\0'; ck_pr_inc_32(&sig->refct); meth->sig = sig; if (requestcb) { meth->cb = *requestcb; } meth->accept_fd = -1; ck_pr_inc_32(&ep->stat.objects.methods); meth->refct=1; } return meth; }
// 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; }
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; }
rwdts_appconf_t *rwdts_appconf_group_create(rwdts_api_t *apih, rwdts_xact_t* xact, rwdts_appconf_cbset_t *cbset) { rw_status_t rs; RW_ASSERT(cbset); RW_ASSERT(cbset->config_apply); if (cbset == NULL) { RWDTS_API_LOG_XACT_EVENT(apih, xact, RwDtsApiLog_notif_AppconfError, "AppconfGroup Create invalid callback param", apih->client_path); return NULL; } if (!cbset->config_apply) { RWDTS_API_LOG_XACT_EVENT(apih, xact, RwDtsApiLog_notif_AppconfError, "AppconfGroup Create invalid config apply param", apih->client_path); return NULL; } rwdts_appconf_t *ac = RW_MALLOC0_TYPE(sizeof(rwdts_appconf_t), rwdts_appconf_t); ac->apih = apih; memcpy(&ac->cb, cbset, sizeof(ac->cb)); rs = rwdts_api_group_create(ac->apih, rwdts_appconf_xact_init, rwdts_appconf_xact_deinit, rwdts_appconf_xact_event, ac, &ac->group); RW_ASSERT(rs == RW_STATUS_SUCCESS); RW_ASSERT(ac->group); if ((rs != RW_STATUS_SUCCESS) || !ac->group) { RWDTS_API_LOG_XACT_EVENT(apih, xact, RwDtsApiLog_notif_AppconfError, "AppconfGroup API Create failure", apih->client_path); return NULL; } ac->phase_complete = false; ac->reg_pend = 0; ac->group->xact = xact; if (xact) { rwdts_xact_ref(xact,__PRETTY_FUNCTION__, __LINE__); } rwdts_appconf_ref(ac); ac->regn_timer = rwsched_dispatch_source_create(apih->tasklet, RWSCHED_DISPATCH_SOURCE_TYPE_TIMER, 0, 0, apih->client.rwq); rwsched_dispatch_source_set_event_handler_f(apih->tasklet, ac->regn_timer, rwdts_appconf_regn_check_timer); rwsched_dispatch_set_context(apih->tasklet, ac->regn_timer, ac); rwsched_dispatch_source_set_timer(apih->tasklet, ac->regn_timer, dispatch_time(DISPATCH_TIME_NOW, 1*NSEC_PER_SEC), (60 * NSEC_PER_SEC), 0); rwsched_dispatch_resume(apih->tasklet, ac->regn_timer); return ac; }