static int lua_general_resume(noit_lua_resume_info_t *ri, int nargs) { const char *err = NULL; int status, base, rv = 0; #if LUA_VERSION_NUM >= 502 status = lua_resume(ri->coro_state, ri->lmc->lua_state, nargs); #else status = lua_resume(ri->coro_state, nargs); #endif switch(status) { case 0: break; case LUA_YIELD: lua_gc(ri->coro_state, LUA_GCCOLLECT, 0); return 0; default: /* The complicated case */ base = lua_gettop(ri->coro_state); if(base>=0) { if(lua_isstring(ri->coro_state, base-1)) { err = lua_tostring(ri->coro_state, base-1); noitL(nlerr, "err -> %s\n", err); } } rv = -1; } lua_general_ctx_free(ri); return rv; }
static int lua_general_resume(mtev_lua_resume_info_t *ri, int nargs) { const char *err = NULL; int status, base, rv = 0; mtevAssert(pthread_equal(pthread_self(), ri->bound_thread)); #if LUA_VERSION_NUM >= 502 status = lua_resume(ri->coro_state, ri->lmc->lua_state, nargs); #else status = lua_resume(ri->coro_state, nargs); #endif switch(status) { case 0: break; case LUA_YIELD: lua_gc(ri->coro_state, LUA_GCCOLLECT, 0); return 0; default: /* The complicated case */ mtevL(nlerr, "lua coro resume failed: %d\n", status); base = lua_gettop(ri->coro_state); if(base>0) { mtev_lua_traceback(ri->coro_state); base = lua_gettop(ri->coro_state); if(lua_isstring(ri->coro_state, base)) { err = lua_tostring(ri->coro_state, base); mtevL(nlerr, "lua error: %s\n", err); } } tragic_failure(ri->lmc->self); rv = -1; } lua_general_ctx_free(ri); return rv; }
static int lua_general_handler(noit_module_generic_t *self) { int status, rv; lua_general_conf_t *conf = get_config(self); lua_module_closure_t *lmc = &conf->lmc; noit_lua_resume_info_t *ri = NULL;; const char *err = NULL; char errbuf[128]; lua_State *L; if(!lmc || !conf || !conf->module || !conf->function) { goto boom; } ri = lua_general_new_resume_info(lmc); L = ri->coro_state; lua_getglobal(L, "require"); lua_pushstring(L, conf->module); rv = lua_pcall(L, 1, 1, 0); if(rv) { int i; noitL(nlerr, "lua: require %s failed\n", conf->module); i = lua_gettop(L); if(i>0) { if(lua_isstring(L, i)) { const char *err; size_t len; err = lua_tolstring(L, i, &len); noitL(nlerr, "lua: %s\n", err); } } lua_pop(L,i); goto boom; } lua_pop(L, lua_gettop(L)); noit_lua_pushmodule(L, conf->module); if(lua_isnil(L, -1)) { lua_pop(L, 1); snprintf(errbuf, sizeof(errbuf), "no such module: '%s'", conf->module); err = errbuf; goto boom; } lua_getfield(L, -1, conf->function); lua_remove(L, -2); if(!lua_isfunction(L, -1)) { lua_pop(L, 1); snprintf(errbuf, sizeof(errbuf), "no function '%s' in module '%s'", conf->function, conf->module); err = errbuf; goto boom; } status = lmc->resume(ri, 0); if(status == 0) return 0; /* If we've failed, resume has freed ri, so we should just return. */ noitL(nlerr, "lua dispatch error: %d\n", status); return 0; boom: if(err) noitL(nlerr, "lua dispatch error: %s\n", err); if(ri) lua_general_ctx_free(ri); return 0; }