static int ngx_http_lua_uthread_spawn(lua_State *L) { int n; ngx_http_request_t *r; ngx_http_lua_ctx_t *ctx; ngx_http_lua_co_ctx_t *coctx = NULL; n = lua_gettop(L); lua_pushlightuserdata(L, &ngx_http_lua_request_key); lua_rawget(L, LUA_GLOBALSINDEX); r = lua_touserdata(L, -1); lua_pop(L, 1); if (r == NULL) { return luaL_error(L, "no request found"); } ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); if (ctx == NULL) { return luaL_error(L, "no request ctx found"); } ngx_http_lua_coroutine_create_helper(L, r, ctx, &coctx); /* anchor the newly created coroutine into the Lua registry */ lua_pushlightuserdata(L, &ngx_http_lua_coroutines_key); lua_rawget(L, LUA_REGISTRYINDEX); lua_pushvalue(L, -2); coctx->co_ref = luaL_ref(L, -2); lua_pop(L, 1); if (n > 1) { lua_replace(L, 1); lua_xmove(L, coctx->co, n - 1); } coctx->is_uthread = 1; ctx->uthreads++; coctx->co_status = NGX_HTTP_LUA_CO_RUNNING; ctx->co_op = NGX_HTTP_LUA_USER_THREAD_RESUME; ctx->cur_co_ctx->thread_spawn_yielded = 1; if (ngx_http_lua_post_thread(r, ctx, ctx->cur_co_ctx) != NGX_OK) { return luaL_error(L, "out of memory"); } coctx->parent_co_ctx = ctx->cur_co_ctx; ctx->cur_co_ctx = coctx; ngx_http_lua_probe_user_thread_spawn(r, L, coctx->co); return lua_yield(L, 1); }
static int ngx_http_lua_on_abort(lua_State *L) { ngx_http_request_t *r; ngx_http_lua_ctx_t *ctx; ngx_http_lua_co_ctx_t *coctx = NULL; ngx_http_lua_loc_conf_t *llcf; lua_pushlightuserdata(L, &ngx_http_lua_request_key); lua_rawget(L, LUA_GLOBALSINDEX); r = lua_touserdata(L, -1); lua_pop(L, 1); if (r == NULL) { return luaL_error(L, "no request found"); } ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); if (ctx == NULL) { return luaL_error(L, "no request ctx found"); } if (ctx->on_abort_co_ctx) { lua_pushnil(L); lua_pushliteral(L, "duplicate call"); return 2; } llcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_module); if (!llcf->check_client_abort) { lua_pushnil(L); lua_pushliteral(L, "lua_check_client_abort is off"); return 2; } ngx_http_lua_coroutine_create_helper(L, r, ctx, &coctx); lua_pushlightuserdata(L, &ngx_http_lua_coroutines_key); lua_rawget(L, LUA_REGISTRYINDEX); lua_pushvalue(L, -2); dd("on_wait thread 1: %p", lua_tothread(L, -1)); coctx->co_ref = luaL_ref(L, -2); lua_pop(L, 1); coctx->is_uthread = 1; ctx->on_abort_co_ctx = coctx; dd("on_wait thread 2: %p", coctx->co); coctx->co_status = NGX_HTTP_LUA_CO_SUSPENDED; coctx->parent_co_ctx = ctx->cur_co_ctx; lua_pushinteger(L, 1); return 1; }
static int ngx_http_lua_coroutine_create(lua_State *L) { ngx_http_request_t *r; ngx_http_lua_ctx_t *ctx; r = ngx_http_lua_get_req(L); if (r == NULL) { return luaL_error(L, "no request found"); } ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); if (ctx == NULL) { return luaL_error(L, "no request ctx found"); } return ngx_http_lua_coroutine_create_helper(L, r, ctx, NULL); }
static int ngx_http_lua_coroutine_create(lua_State *L) { return ngx_http_lua_coroutine_create_helper(L, NULL, NULL, NULL); }