static int luv_thread_gc(lua_State* L) { luv_thread_t* tid = luv_check_thread(L, 1); free(tid->code); tid->code = NULL; tid->len = 0; luv_thread_arg_clear(&tid->arg); return 0; }
static void luv_queue_message_release(luv_msg_t* msg) { if (msg) { luv_thread_arg_clear(&(msg->arg)); free(msg); msg = NULL; } }
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 void luv_thread_cb(void* varg) { int top, errfunc; //acquire vm and get top luv_thread_t* thd = (luv_thread_t*)varg; lua_State* L = acquire_vm_cb(); top = lua_gettop(L); //push traceback lua_pushcfunction(L, traceback); errfunc = lua_gettop(L); //push lua function, thread entry if (luaL_loadbuffer(L, thd->code, thd->len, "=thread") == 0) { int i, ret; //push parameter for real thread function i = luv_thread_arg_push(L, &thd->arg, LUVF_THREAD_UHANDLE); assert(i == thd->arg.argc); ret = lua_pcall(L, thd->arg.argc, 0, errfunc); switch (ret) { case LUA_OK: break; case LUA_ERRMEM: fprintf(stderr, "System Error in thread: %s\n", lua_tostring(L, -1)); lua_pop(L, 1); break; case LUA_ERRRUN: case LUA_ERRSYNTAX: case LUA_ERRERR: default: fprintf(stderr, "Uncaught Error in thread: %s\n", lua_tostring(L, -1)); lua_pop(L, 1); break; } luv_thread_arg_clear(L, &thd->arg, LUVF_THREAD_UHANDLE); } else { fprintf(stderr, "Uncaught Error in thread: %s\n", lua_tostring(L, -1)); //pop errmsg lua_pop(L, 1); } //balance stack of traceback lua_pop(L, 1); assert(top == lua_gettop(L)); release_vm_cb(L); }
static void luv_after_work_cb(uv_work_t* req, int status) { luv_work_t* work = req->data; luv_work_ctx_t* ctx = work->ctx; lua_State*L = ctx->L; int i; lua_rawgeti(L, LUA_REGISTRYINDEX, ctx->after_work_cb); i = luv_thread_arg_push(L, &work->arg); if (lua_pcall(L, i, 0, 0)) { fprintf(stderr, "Uncaught Error in thread: %s\n", lua_tostring(L, -1)); } //ref down to ctx lua_pushlightuserdata(L, work); lua_pushnil(L); lua_rawset(L, LUA_REGISTRYINDEX); luv_thread_arg_clear(&work->arg); free(work); }
static int luv_work_gc(lua_State *L) { luv_work_t* work = luv_check_work(L, 1); luv_thread_arg_clear(&work->arg); return 0; }