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); }
static void async_cb(uv_async_t *handle) { luv_work_t*work = handle->data; luv_work_ctx_t* ctx = work->ctx; lua_State*L = ctx->L; int i; lua_rawgeti(L, LUA_REGISTRYINDEX, ctx->async_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)); } }
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 int luv_queue_channel_recv(lua_State* L) { luv_queue_t* q = luv_queue_check_queue_t(L); int timeout = luv_queue_lua_arg_integer(L, 2, 1, -1, queue_usage_recv); luv_msg_t* msg = luv_queue_recv(q, timeout); if (msg) { int ret = luv_thread_arg_push(L, &(msg->arg)); luv_queue_message_release(msg); return ret; } else { lua_pushnil(L); } return 1; }
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 void luv_thread_cb(void* varg) { luv_thread_t* thd = (luv_thread_t*)varg; lua_State* L = acquire_vm_cb(); if (luaL_loadbuffer(L, thd->code, thd->len, "=thread") == 0) { int top = lua_gettop(L); int i = luv_thread_arg_push(L, &thd->arg); for (i = 0; i < thd->arg.argc; i++) { if (thd->arg.argv[i].type == LUA_TUSERDATA) { lua_pushlightuserdata(L, thd->arg.argv[i].val.userdata); lua_pushvalue(L, top + i + 1); lua_rawset(L, LUA_REGISTRYINDEX); } } if (lua_pcall(L, i, 0, 0)) { fprintf(stderr, "Uncaught Error in thread: %s\n", lua_tostring(L, -1)); } for (i = 0; i < thd->arg.argc; i++) { if (thd->arg.argv[i].type == LUA_TUSERDATA) { lua_pushlightuserdata(L, thd->arg.argv[i].val.userdata); lua_rawget(L, LUA_REGISTRYINDEX); lua_pushnil(L); lua_setmetatable(L, -2); lua_pop(L, 1); lua_pushlightuserdata(L, thd->arg.argv[i].val.userdata); lua_pushnil(L); lua_rawset(L, LUA_REGISTRYINDEX); } } } else { fprintf(stderr, "Uncaught Error: %s\n", lua_tostring(L, -1)); } release_vm_cb(L); }
static void luv_queue_async_callback(uv_async_t *handle) { luv_queue_t* queue = handle->data; if (queue == NULL) { printf("queue"); return; } lua_State* L = queue->L; if (L == NULL) { printf("L"); return; } while (1) { luv_msg_t* msg = luv_queue_recv(queue, 0); if (msg == NULL) { break; } // callback lua_rawgeti(L, LUA_REGISTRYINDEX, queue->async_cb); if (lua_isnil(L, -1)) { luv_queue_message_release(msg); continue; } // args int ret = luv_thread_arg_push(L, &(msg->arg)); luv_queue_message_release(msg); msg = NULL; // call if (lua_pcall(L, ret, 0, 0)) { fprintf(stderr, "Uncaught Error in thread async: %s\n", lua_tostring(L, -1)); } } }