static void tls_thread(void* arg) { ASSERT(NULL == uv_key_get(&tls_key)); uv_key_set(&tls_key, arg); ASSERT(arg == uv_key_get(&tls_key)); uv_key_set(&tls_key, NULL); ASSERT(NULL == uv_key_get(&tls_key)); }
/* initialize thread local key for the base kernel proc */ void baseinit(hproc_t* p) { if(uv_key_create(&prdakey)) panic("TLS key create failed"); uv_key_set(&prdakey, p); }
static void luv_work_cb(uv_work_t* req) { uv_thread_t tid = uv_thread_self(); luv_work_t* work = req->data; luv_work_ctx_t* ctx = work->ctx; lua_State *L = uv_key_get(&L_key); int top; if (L == NULL) { /* should vm reuse in pool? */ L = acquire_vm_cb(); uv_key_set(&L_key, L); } top = lua_gettop(L); if (luaL_loadbuffer(L, ctx->code, ctx->len, "=pool") == 0) { int i = luv_thread_arg_push(L, &work->arg); if (lua_pcall(L, i, LUA_MULTRET, 0)) { fprintf(stderr, "Uncaught Error in thread: %s\n", lua_tostring(L, -1)); } luv_thread_arg_set(L, &work->arg, top, lua_gettop(L)); } else { fprintf(stderr, "Uncaught Error: %s\n", lua_tostring(L, -1)); } //release_vm_cb(L); }
void RecursiveLockGuard::release() { void* lkey = uv_key_get(mutex_key); if (lkey) { uv_mutex_unlock(mutex); uv_key_set(mutex_key, 0); } locked = false; }
RecursiveLockGuard::RecursiveLockGuard(uv_mutex_t* mutex_, uv_key_t* mutex_key_) : mutex(mutex_), mutex_key(mutex_key_), locked(true) { void* lkey = uv_key_get(mutex_key); if (!lkey) { uv_mutex_lock(mutex); uv_key_set(mutex_key, (void*)1); } }
CAMLprim value camluv_key_set(value key, value key_value) { CAMLparam1(key); camluv_key_t *camluv_key = camluv_key_struct_val(key); uv_key_set(&(camluv_key->uv_key), (void *)key_value); CAMLreturn(Val_unit); }
static void luv_work_cb(uv_work_t* req) { uv_thread_t tid = uv_thread_self(); luv_work_t* work = req->data; luv_work_ctx_t* ctx = work->ctx; lua_State *L = uv_key_get(&L_key); int top; if (L == NULL) { /* vm reuse in threadpool */ L = acquire_vm_cb(); uv_key_set(&L_key, L); } top = lua_gettop(L); lua_pushlstring(L, ctx->code, ctx->len); lua_rawget(L, LUA_REGISTRYINDEX); if (lua_isnil(L, -1)) { lua_pop(L, 1); lua_pushlstring(L, ctx->code, ctx->len); if (luaL_loadbuffer(L, ctx->code, ctx->len, "=pool") != 0) { fprintf(stderr, "Uncaught Error: %s\n", lua_tostring(L, -1)); lua_pop(L, 2); lua_pushnil(L); } else { lua_pushvalue(L, -1); lua_insert(L, lua_gettop(L) - 2); lua_rawset(L, LUA_REGISTRYINDEX); } } if (lua_isfunction(L, -1)) { int i = luv_thread_arg_push(L, &work->arg); if (lua_pcall(L, i, LUA_MULTRET, 0)) { fprintf(stderr, "Uncaught Error in thread: %s\n", lua_tostring(L, -1)); } luv_thread_arg_clear(&work->arg); luv_thread_arg_set(L, &work->arg, top + 1, lua_gettop(L)); lua_settop(L, top); } else { fprintf(stderr, "Uncaught Error: %s can't be work entry\n", lua_typename(L, lua_type(L,-1))); } }
static uvc_thread_env *uvc_get_env(){ uvc_ctx *ctx = NULL; uv_once(&once,uvc_init); uvc_thread_env *env=(uvc_thread_env *)uv_key_get(&uvc_key); if(env==NULL){ env=(uvc_thread_env *)malloc(sizeof(uvc_thread_env)); memset(env,0,sizeof(uvc_thread_env)); env->loop = uv_loop_new(); queue_init(&env->pending_queue); queue_init(&env->ready_queue); ctx = (uvc_ctx *)malloc(sizeof(uvc_ctx)); memset(ctx, 0, sizeof(uvc_ctx)); coro_stack_alloc(&ctx->stack, 0); coro_create(&ctx->cur, NULL, NULL, ctx->stack.sptr, ctx->stack.ssze); sprintf(ctx->name, "ROOT"); env->schedule_task = ctx; env->runing_task = ctx; ctx->status = UVC_STATUS_RUNING; uv_key_set(&uvc_key,env); } return env; }
/* * tramp is the first thread component that runs as the new kernel process. it initializes * bare kernel procs and host kernel procs, binds them to the new thread and runs their * start up function. */ void tramp(void *arg) { kproc_t* p; Osdep *os; /* get the process */ p = (kproc_t*)arg; os = p->os; os->self = uv_thread_self(); /* make it the current proc in TLS */ uv_key_set(&prdakey, p); /* start the process */ trace(TRACE_DEBUG, "kernel/tramp: starting kernel process '%s'",p->text); p->func(p->arg); trace(TRACE_DEBUG, "kernel/tramp: kernel process '%s' exited, releasing resources",p->text); /* the process terminated, so clean up */ pexit("{Tramp}", 0); }
static mrb_value mrb_uv_key_set(mrb_state *mrb, mrb_value self) { uv_key_t *key; void *p; mrb_value new_val; mrb_value ary; mrb_get_args(mrb, "o", &new_val); if (mrb_type(new_val) < MRB_TT_HAS_BASIC) { mrb_raisef(mrb, E_TYPE_ERROR, "cannot store value without basic: %S", new_val); } key = (uv_key_t*)mrb_uv_get_ptr(mrb, self, &mrb_uv_key_type); p = uv_key_get(key); ary = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "values")); mrb_assert(mrb_array_p(ary)); if (p) { /* remove value */ int i, dst; for (i = 0, dst = 0; i < RARRAY_LEN(ary); ++i) { mrb_value v = RARRAY_PTR(ary)[i]; if (mrb_ptr(v) != p) { mrb_ary_ptr(ary)->ptr[dst++] = v; } } RARRAY_LEN(ary) = dst; } uv_key_set(key, mrb_ptr(new_val)); mrb_ary_push(mrb, ary, new_val); /* protect from GC */ return new_val; }
int main(int argc, char *argv[]) { int rc; uv_loop_t *loop; struct sockaddr local_addr; parse_opts(argc, argv); #ifndef _WIN32 if (xsignal) { return signal_process(xsignal, pidfile); } if (!password) { print_usage(argv[0]); return 1; } #endif #ifndef _WIN32 if (daemon_mode) { if (daemonize()) { return 1; } if (already_running(pidfile)) { logger_stderr("xsocksd already running."); return 1; } } #endif init(); loop = uv_default_loop(); rc = resolve_addr(local_addrbuf, &local_addr); if (rc) { logger_stderr("invalid local address"); return 1; } if (udprelay) { udprelay_init(); } if (concurrency <= 1) { struct server_context ctx; ctx.local_addr = &local_addr; ctx.udprelay = udprelay; ctx.resolver = 1; ctx.udp_fd = create_socket(SOCK_DGRAM, 0); uv_tcp_init(loop, &ctx.tcp); rc = uv_tcp_bind(&ctx.tcp, &local_addr, 0); if (rc) { logger_stderr("tcp bind error: %s", uv_strerror(rc)); return 1; } rc = uv_listen((uv_stream_t*)&ctx.tcp, 128, client_accept_cb); if (rc == 0) { logger_log(LOG_INFO, "listening on %s", local_addrbuf); #ifndef _WIN32 setup_signal(loop, signal_cb, &ctx); #endif struct resolver_context *dns = resolver_init(loop, MODE_IPV4, nameserver_num == 0 ? NULL : nameservers, nameserver_num); uv_key_set(&thread_resolver_key, dns); if (udprelay) { udprelay_start(loop, &ctx); } uv_run(loop, UV_RUN_DEFAULT); close_loop(loop); resolver_destroy(dns); } else { logger_stderr("listen error: %s", uv_strerror(rc)); } } else { #ifndef _WIN32 struct server_context *servers = calloc(concurrency, sizeof(servers[0])); for (int i = 0; i < concurrency; i++) { struct server_context *ctx = servers + i; ctx->index = i; ctx->tcp_fd = create_socket(SOCK_STREAM, 1); ctx->udp_fd = create_socket(SOCK_DGRAM, 1); ctx->udprelay = udprelay; ctx->resolver = 1; ctx->accept_cb = client_accept_cb; ctx->nameservers = nameservers; ctx->nameserver_num = nameserver_num; ctx->local_addr = &local_addr; rc = uv_sem_init(&ctx->semaphore, 0); rc = uv_thread_create(&ctx->thread_id, consumer_start, ctx); } logger_log(LOG_INFO, "listening on %s", local_addrbuf); setup_signal(loop, signal_cb, servers); uv_run(loop, UV_RUN_DEFAULT); close_loop(loop); for (int i = 0; i < concurrency; i++) { uv_sem_wait(&servers[i].semaphore); } free(servers); #else logger_stderr("don't support multithreading."); return 1; #endif } if (udprelay) { udprelay_destroy(); } uv_key_delete(&thread_resolver_key); #ifndef _WIN32 if (daemon_mode) { delete_pidfile(pidfile); } #endif logger_exit(); return 0; }
wsn_thread_ctx_t* wsn_set_thread_ctx(wsn_thread_ctx_t *thread_ctx) { wsn_thread_ctx_t *old_ctx = (wsn_thread_ctx_t*)uv_key_get(&tls_key_); uv_key_set(&tls_key_, thread_ctx); return old_ctx; }