/* * Arguments: evq_udata, ev_ludata, [callback (function)] * Returns: evq_udata | callback (function) */ static int levq_callback (lua_State *L) { struct event_queue *evq = checkudata(L, 1, EVQ_TYPENAME); struct event *ev = levq_toevent(L, 2); lua_State *NL = evq->L; const int top = lua_gettop(L); lua_assert(ev && !event_deleted(ev)); if (top < 3) { lua_rawgeti(NL, EVQ_CORO_CALLBACK, ev->ev_id); lua_xmove(NL, L, 1); } else { ev->flags &= ~(EVENT_CALLBACK | EVENT_CALLBACK_CORO); if (!lua_isnoneornil(L, 3)) { ev->flags |= EVENT_CALLBACK | (lua_isthread(L, 3) ? EVENT_CALLBACK_CORO : 0); } lua_settop(L, 3); lua_xmove(L, NL, 1); lua_rawseti(NL, EVQ_CORO_CALLBACK, ev->ev_id); lua_settop(L, 1); } return 1; }
void LuaEngineMgr::ResumeLuaThread(int ref) { CREATE_L_PTR; lua_State* expectedThread = NULL; lua_rawgeti(L, LUA_REGISTRYINDEX, ref); if(lua_isthread(L, -1)) expectedThread = lua_tothread(L, -1); if(expectedThread != NULL) { //push ourself on the stack lua_pushthread(expectedThread); //move the thread to the main lu state(and pop it off) lua_xmove(expectedThread, L, 1); if(lua_rawequal(L, -1, -2)) { lua_pop(L, 2); int res = lua_resume(expectedThread, lua_gettop(expectedThread)); if(res != LUA_YIELD && res) report(expectedThread); } else lua_pop(L, 2); luaL_unref(L, LUA_REGISTRYINDEX, ref); } }
/* ** Auxiliary function used by several library functions: check for ** an optional thread as function's first argument and set 'arg' with ** 1 if this argument is present (so that functions can skip it to ** access their other arguments) */ static lua_State *getthread (lua_State *L, int *arg) { if (lua_isthread(L, 1)) { *arg = 1; return lua_tothread(L, 1); } else { *arg = 0; return L; /* function will operate over current thread */ } }
int LuaTimeline::lua_pushTask(lua_State* L) { if(!lua_isthread(L, 1))return 0; lua_State *t=lua_tothread(L, 1); lua_pushthread(t); int ref=luaL_ref(t, LUA_REGISTRYINDEX); inst()->pushTask(LuaTask(t, ref, inst()->timeSec, inst()->currentTask)); lua_pushinteger(L, ref); return 1; }
static lua_State *getthread (lua_State *L, int *arg) { if (lua_isthread(L, 1)) { *arg = 1; return lua_tothread(L, 1); } else { *arg = 0; return L; } }
static int Queue_push(lua_State *L) { //lua_State *t = lua_tothread(L, 1); //int p = lua_tonumber(L, 2); //printf("prioridade %i", p); int t = lua_isthread(L, 1); int p = lua_isnumber(L, 2); int v1 = lua_tonumber(L, 1); int v2 = lua_tonumber(L, 2); printf("%i %i %i %i", t, p, v1, v2); return 0; }
/** @internal Helper for calling the entrypoint. */ static inline int l_ffi_call(lua_State *L, int argc) { int status = lua_pcall(L, argc, 1, 0); if (status != 0) { fprintf(stderr, "error: %s\n", lua_tostring(L, -1)); lua_pop(L, 1); return kr_error(EIO); } if (lua_isnumber(L, -1)) { /* Return code */ status = lua_tonumber(L, -1); } else if (lua_isthread(L, -1)) { /* Continuations */ status = l_ffi_defer(lua_tothread(L, -1)); } lua_pop(L, 1); return status; }
/* Store the threads in a global variable so they are not cleaned up by the * garbage collector. */ static int clua_store_thread(lua_State *L, int idx) /* {{{ */ { if (idx < 0) idx += lua_gettop(L) + 1; /* Copy the thread pointer */ lua_pushvalue(L, idx); /* +1 = 3 */ if (!lua_isthread(L, -1)) { lua_pop(L, 3); /* -3 = 0 */ return (-1); } luaL_ref(L, LUA_REGISTRYINDEX); lua_pop(L, 1); /* -1 = 0 */ return (0); } /* }}} int clua_store_thread */
/* string tag string userstring thread co (default nil) integer level */ static int ltrace(lua_State *L) { struct skynet_context * context = lua_touserdata(L, lua_upvalueindex(1)); const char * tag = luaL_checkstring(L, 1); const char * user = luaL_checkstring(L, 2); if (lua_isthread(L, 3)) { lua_State * co = lua_tothread (L, 3); struct source_info si[MAX_LEVEL]; lua_Debug d; int level = luaL_checkinteger(L, 4); int index = 0; do { if (!lua_getstack(co, level, &d)) break; lua_getinfo(co, "Sl", &d); level++; si[index].source = d.source; si[index].line = d.currentline; if (d.currentline >= 0) ++index; } while (index < MAX_LEVEL); switch (index) { case 1: skynet_error(context, "<TRACE %s> %" PRId64 " %s : %s:%d", tag, get_time(), user, si[0].source, si[0].line); break; case 2: skynet_error(context, "<TRACE %s> %" PRId64 " %s : %s:%d %s:%d", tag, get_time(), user, si[0].source, si[0].line, si[1].source, si[1].line ); break; case 3: skynet_error(context, "<TRACE %s> %" PRId64 " %s : %s:%d %s:%d %s:%d", tag, get_time(), user, si[0].source, si[0].line, si[1].source, si[1].line, si[2].source, si[2].line ); break; default: skynet_error(context, "<TRACE %s> %" PRId64 " %s", tag, get_time(), user); break; } return 0; } skynet_error(context, "<TRACE %s> %" PRId64 " %s", tag, get_time(), user); return 0; }
int luaT_lua_pointer(lua_State *L) { if(lua_type(L, 1) == 10) /* luajit cdata */ { /* we want the pointer holded by cdata */ /* not the pointer on the cdata object */ const void* ptr = *((void**)lua_topointer(L, 1)); lua_pushnumber(L, (long)(ptr)); return 1; } else if (luaT_iscdata(L, 1)) /* luaffi cdata */ { void** ptr = (void**)lua_touserdata(L, 1); lua_pushnumber(L, (long)(ptr[4])); return 1; } else if(lua_isuserdata(L, 1)) { void **ptr; luaL_argcheck(L, luaT_typename(L, 1), 1, "Torch object expected"); ptr = lua_touserdata(L, 1); lua_pushnumber(L, (long)(*ptr)); return 1; } else if(lua_istable(L, 1) || lua_isthread(L, 1) || lua_isfunction(L, 1)) { const void* ptr = lua_topointer(L, 1); lua_pushnumber(L, (long)(ptr)); return 1; } else if(lua_isstring(L, 1)) { const char* ptr = lua_tostring(L, 1); lua_pushnumber(L, (long)(ptr)); return 1; } else luaL_error(L, "Torch object, table, thread, cdata or function expected"); return 0; }
int lua_print(lua_State * luastate) { int nargs = lua_gettop(luastate); lfStr t; for (int i=1; i <= nargs; i++) { if (lua_istable(luastate, i)) t += "table"; else if (lua_isnone(luastate, i)) t += "none"; else if (lua_isnil(luastate, i)) t += "nil"; else if (lua_isboolean(luastate, i)) { if (lua_toboolean(luastate, i) != 0) t += "true"; else t += "false"; } else if (lua_isfunction(luastate, i)) t += "function"; else if (lua_islightuserdata(luastate, i)) t += "lightuserdata"; else if (lua_isthread(luastate, i)) t += "thread"; else { const char * str = lua_tostring(luastate, i); if (str) t += lua_tostring(luastate, i); else t += lua_typename(luastate, lua_type(luastate, i)); } if (i!=nargs) t += "\t"; } Sys_Printf("%s\n", t.c_str()); return 0; }
int luaT_lua_pointer(lua_State *L) { if(lua_isuserdata(L, 1)) { void **ptr; luaL_argcheck(L, luaT_typename(L, 1), 1, "Torch object expected"); ptr = lua_touserdata(L, 1); lua_pushnumber(L, (long)(*ptr)); return 1; } else if(lua_istable(L, 1) || lua_isthread(L, 1) || lua_isfunction(L, 1)) { const void* ptr = lua_topointer(L, 1); lua_pushnumber(L, (long)(ptr)); return 1; } else luaL_error(L, "Torch object, table, thread or function expected"); return 0; }
void G_LuaCollectGarbage(void) { lvm_t *vm; lua_State *p; int i, n, m; for(i = 0; i < NUM_VMS; i++) { vm = lVM[i]; if(vm) { n = lua_gettop(vm->L); for(m = n; m > 0; m--) { if(lua_isthread(vm->L, m)) { p = lua_tothread(vm->L, m); lua_gc(p, LUA_GCCOLLECT, 0); } } lua_gc(vm->L, LUA_GCCOLLECT, 0); } } }
void G_LuaNumThreads(void) { lvm_t* vm = lVM[0]; if(vm) { lua_State *p; int n = lua_gettop(vm->L); int i, cnt = 0; for(i = 0; i <= n; i++) { if(lua_isthread(vm->L, i)) { cnt++; p = lua_tothread(vm->L, i); if(lua_status(p) == LUA_YIELD) { G_Printf("lua thread %d is YIELDED\n", i); } else if(lua_status(vm->L) == 0) { G_Printf("lua thread %d is RUNNING\n", i); } } } G_Printf("Total lua thread count: %d\n", cnt); } }
qboolean G_LuaResume(lvm_t *vm, lua_State *T, char *func, int nargs) { int res = lua_resume(T, NULL, nargs); if(res == LUA_ERRRUN) { LUA_LOG("Lua: %s error running lua script: %s\n", func, lua_tostring(T, -1)); G_Printf(S_COLOR_YELLOW "Lua: %s error running lua script: %s\n", func, lua_tostring(T, -1)); lua_pop(T, 1); vm->error++; return qfalse; } else if(res == LUA_ERRMEM) { LUA_LOG("Lua: memory allocation error #2 ( %s )\n", vm->filename); vm->error++; return qfalse; } else if(res == LUA_ERRERR) { LUA_LOG("Lua: traceback error ( %s )\n", vm->filename); G_Printf(S_COLOR_YELLOW "Lua: traceback error ( %s )\n", vm->filename); vm->error++; return qfalse; } if(vm->L != T) { // this is a thread int n = lua_gettop(vm->L); int i; lua_State *p; for(i = 0; i <= n; i++) { if(lua_isthread(vm->L, i)) { p = lua_tothread(vm->L, i); if(p == T) { lua_remove(vm->L, i); G_LuaCollectGarbage(); } } } } return qtrue; }
static void ngx_http_lua_request_cleanup(void *data) { ngx_http_request_t *r = data; ngx_http_lua_main_conf_t *lmcf; ngx_http_lua_ctx_t *ctx; lua_State *L; dd("(lua-request-cleanup) force request coroutine quit"); lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module); L = lmcf->lua; ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); /* force coroutine handling the request quit */ if (ctx == NULL) { return; } if (ctx->cleanup) { *ctx->cleanup = NULL; ctx->cleanup = NULL; } lua_getfield(L, LUA_REGISTRYINDEX, NGX_LUA_CORT_REF); lua_rawgeti(L, -1, ctx->cc_ref); if (lua_isthread(L, -1)) { /* coroutine not finished yet, force quit */ ngx_http_lua_del_thread(r, L, ctx->cc_ref, 1); #if 0 ngx_http_lua_send_chain_link(r, ctx, NULL /* indicate last_buf */); #endif } lua_pop(L, 2); }
bool LuaState::IsOfType(int index, LuaType type) const { switch (type) { case LuaType_Boolean: return lua_isboolean(m_state, index) != 0; case LuaType_Function: return lua_isfunction(m_state, index) != 0; case LuaType_LightUserdata: return lua_islightuserdata(m_state, index) != 0; case LuaType_Nil: return lua_isnil(m_state, index) != 0; case LuaType_None: return lua_isnone(m_state, index) != 0; case LuaType_Number: return lua_isnumber(m_state, index) != 0; case LuaType_String: return lua_isstring(m_state, index) != 0; case LuaType_Table: return lua_istable(m_state, index) != 0; case LuaType_Thread: return lua_isthread(m_state, index) != 0; case LuaType_Userdata: return lua_isuserdata(m_state, index) != 0; } NazaraError("Lua type not handled (0x" + String::Number(type, 16) + ')'); return false; }
int Lua_SuspendLuaThread(lua_State * L) { lua_State * thread = (lua_isthread(L,1)) ? lua_tothread(L,1) : NULL; if(thread == NULL) return luaL_error(L,"LuaEngineMgr","SuspendLuaThread expected Lua coroutine, got NULL."); int waitime = luaL_checkinteger(L,2); if(waitime <= 0) return luaL_error(L,"LuaEngineMgr","SuspendLuaThread expected timer > 0 instead got (%d)",waitime); lua_pushvalue(L,1); int ref = luaL_ref(L,LUA_REGISTRYINDEX); if(ref == LUA_REFNIL || ref == LUA_NOREF) return luaL_error(L,"Error in SuspendLuaThread! Failed to create a valid reference."); TimedEvent * evt = TimedEvent::Allocate(thread,new CallbackP1<LuaEngineMgr,int>(&g_luaMgr,&LuaEngineMgr::ResumeLuaThread,ref),0,waitime,1); sWorld.event_AddEvent(evt); lua_remove(L,1); // remove thread object lua_remove(L,1); // remove timer. //All that remains now are the extra arguments passed to this function. lua_xmove(L,thread,lua_gettop(L)); g_luaMgr.getThreadRefs().insert(ref); return lua_yield(thread,lua_gettop(L)); }
bool LuaWrapper::isThread(int nIndex) { return lua_isthread(m_luaState, nIndex); }
inline bool is<lua_State*>(lua_State* L, int index) { LUNA_INDEX_ASSERT(L, index); return(lua_isthread(L, index)); }
bool Environment::isThread(int index) { return lua_isthread(L, index); }
/** Check if stack value is a thread. * @param idx stack index of value * @return true if value is a thread, false otherwise */ bool LuaContext::is_thread(int idx) { return lua_isthread(__L, idx); }
JNIEXPORT jboolean JNICALL Java_m_lua_Lua_isThread (JNIEnv* env, jobject thiz, jlong nativeObj, jint idx) { pushJNIEnv(env, nativeObj); return (jboolean) lua_isthread((lua_State*) nativeObj, idx); }
static bool strictCheckType(lua_State* l, int index) { return lua_isthread(l, index); }
//***************************************************************************** bool LuaUtils::TransferValueToStack(LuaStack inStack, LuaStack outStack, int ntop, int levels, const char *varname) { if (levels < 0) return false; // convert relative to absolute indexing if necessary if (ntop < 0) ntop = (lua_gettop(inStack) + 1 + ntop); lua_newtable(outStack); // push variable name if (varname != NULL) { lua_pushstring(outStack, varname); lua_setfield(outStack, -2, "name"); } // push the variable type int top_type = lua_type(inStack, ntop); lua_pushstring(outStack, lua_typename(inStack, top_type)); lua_setfield(outStack, -2, "type"); // finally push the value if (lua_isnil(inStack, ntop)) { lua_pushnil(outStack); lua_setfield(outStack, -2, "value"); } else if (lua_isboolean(inStack, ntop)) { lua_pushboolean(outStack, lua_toboolean(inStack, ntop)); lua_setfield(outStack, -2, "value"); } else if (lua_isnumber(inStack, ntop)) { lua_pushnumber(outStack, lua_tonumber(inStack, ntop)); lua_setfield(outStack, -2, "value"); } else if (lua_isstring(inStack, ntop)) { lua_pushstring(outStack, lua_tostring(inStack, ntop)); lua_setfield(outStack, -2, "value"); } else if (lua_islightuserdata(inStack, ntop)) { lua_pushlightuserdata(outStack, lua_touserdata(inStack, ntop)); lua_setfield(outStack, -2, "value"); } else if (lua_isuserdata(inStack, ntop) || lua_iscfunction(inStack, ntop) || lua_isfunction(inStack, ntop) || lua_isthread(inStack, ntop)) { lua_pushfstring(outStack, "%p", lua_topointer(inStack, ntop)); lua_setfield(outStack, -2, "value"); } else if (lua_istable(inStack, ntop)) { if (levels == 0) { lua_pushboolean(outStack, true); lua_setfield(outStack, -2, "raw"); // whether to send only a summary! lua_pushfstring(outStack, "%p", lua_topointer(inStack, ntop)); } else { lua_newtable(outStack); int index = 1; lua_pushnil(inStack); while (lua_next(inStack, ntop) != 0) { // printf("%s - %s\n", lua_typename(inStack, lua_type(inStack, -2)), lua_typename(inStack, lua_type(inStack, -1))); int newtop = lua_gettop(inStack); int keyindex = newtop - 1; int valindex = newtop; lua_pushinteger(outStack, index++); lua_newtable(outStack); // uses 'key' at index top-1 and 'value' at index top if (LuaUtils::TransferValueToStack(inStack, outStack, keyindex, 0)) { lua_setfield(outStack, -2, "key"); if (LuaUtils::TransferValueToStack(inStack, outStack, valindex, levels - 1)) lua_setfield(outStack, -2, "value"); } lua_settable(outStack, -3); // remove 'value', keeps 'key' for next iteration lua_pop(inStack, 1); } } lua_setfield(outStack, -2, "value"); } else { lua_pushstring(outStack, "Unknown type."); lua_setfield(outStack, -2, "value"); } return true; }
static bool checkType(lua_State* l, int index) { return lua_isthread(l, index) || lua_isnil(l, index); }
static void var_dump( lua_State* L, int depth ) { // All the different datatypes need to be handled differently if ( lua_isnil( L, -1 ) ) { print_padded_line( depth, "NIL" ); } else if ( lua_isfunction( L, -1 ) ) { print_padded_line( depth, "FUNCTION" ); } else if ( lua_isuserdata( L, -1 ) ) { print_padded_line( depth, "USERDATA" ); } else if ( lua_isthread( L, -1 ) ) { print_padded_line( depth, "THREAD" ); } else if ( lua_isboolean( L, -1 ) ) { print_padded_line( depth, "boolean(%s)", lua_toboolean( L, -1 ) == true ? "true" : "false" ); } else if ( lua_isnumber( L, -1 ) ) { double number = lua_tonumber( L, -1 ); if ( (double)(int)number == number ) { print_padded_line( depth, "integer(%i)", (int)number ); } else { print_padded_line( depth, "float(%f)", number ); } } else if( lua_isstring( L, -1 ) ) { print_padded_line( depth, "string(%d) \"%s\"", lua_strlen( L, -1 ), lua_tostring( L, -1 ) ); } else if( lua_istable( L, -1 ) ) { print_padded_line( depth, "table(%i) {", lua_objlen( L, -1 ) ); // Push nil as first key before calling next lua_pushnil( L ); while ( lua_next(L, -2 ) != 0 ) { if ( lua_isnumber( L, -2 ) ) { print_padded_line( depth + 1, "[%i] =>", lua_tointeger( L, -2 ) ); } else { print_padded_line( depth + 1, "[\"%s\"] =>", lua_tostring( L, -2 ) ); } var_dump( L, depth + 1 ); } print_padded_line( depth, "}" ); } lua_pop( L, 1 ); }