/// release a reference to a Lua value. // @param L the state // @param ref the reference // @function release_ref void release_ref(lua_State *L, Ref ref) { luaL_unref(L,LUA_REGISTRYINDEX,ref); }
static void sfuserdata_caller(sqlite3_context *ctx, int argc, sqlite3_value **argv) { //Get the userdata struct sfuserdata *ud = (struct sfuserdata *)sqlite3_user_data(ctx); //User the func thread to make a new thread and clear the //func thread assert(lua_gettop(ud->funcState) == 0); lua_State *l = lua_newthread(ud->funcState); //[T] int lr = luaL_ref(ud->funcState, LUA_REGISTRYINDEX); //[] //Call the function in the new thread lua_rawgeti(l, LUA_REGISTRYINDEX, ud->funcref); int arg; for(arg=0;arg<argc;++arg) { switch(sqlite3_value_type(argv[arg])) { case SQLITE_TEXT: lua_pushlstring(l, (const char *)sqlite3_value_text(argv[arg]), sqlite3_value_bytes(argv[arg])); break; case SQLITE_INTEGER: case SQLITE_FLOAT: lua_pushnumber(l, sqlite3_value_double(argv[arg])); break; case SQLITE_NULL: lua_pushnil(l); default: luaL_unref(ud->funcState, LUA_REGISTRYINDEX, lr); sqlite3_result_error(ctx, "func received unknown type", -1); return; } } int rc = lua_pcall(l, argc, 1, 0); if(rc != LUA_OK) { assert(lua_type(l, -1) == LUA_TSTRING); sqlite3_result_error(ctx, lua_tostring(l, -1), -1); luaL_unref(ud->funcState, LUA_REGISTRYINDEX, lr); return; } //set the appropriate return value switch(lua_type(l, 1)) { case LUA_TSTRING: { size_t bytes; const char *s = lua_tolstring(l, 1, &bytes); sqlite3_result_text(ctx, s, bytes, SQLITE_TRANSIENT); break; } case LUA_TNUMBER: sqlite3_result_double(ctx, lua_tonumber(l, 1)); break; case LUA_TNIL: sqlite3_result_null(ctx); break; default: sqlite3_result_error(ctx, "func returned disallowed type", -1); break; } //use the func thread to destroy the new thread //clear the func thread luaL_unref(ud->funcState, LUA_REGISTRYINDEX, lr); }
static int setOnTick(lua_State* L) { RoomData* room = reinterpret_cast<RoomData*>(lua_touserdata(L, 1)); luaL_unref(L, LUA_REGISTRYINDEX, room->GetTickReference()); room->SetTickReference(luaL_ref(L, LUA_REGISTRYINDEX)); return 0; }
// Lua: server/socket:close() // server disconnect everything, unref everything // client disconnect and unref itself static int net_close( lua_State* L, const char* mt ) { NODE_DBG("net_close is called.\n"); bool isserver = false; int i = 0; lnet_userdata *nud = NULL, *skt = NULL; nud = (lnet_userdata *)luaL_checkudata(L, 1, mt); luaL_argcheck(L, nud, 1, "Server/Socket expected"); if(nud == NULL) return 0; if(nud->pesp_conn == NULL) return 0; if (mt!=NULL && c_strcmp(mt, "net.server")==0) isserver = true; else if (mt!=NULL && c_strcmp(mt, "net.socket")==0) isserver = false; else { NODE_DBG("wrong metatable for net_close.\n"); return 0; } if(isserver && nud->pesp_conn->type == ESPCONN_TCP && tcpserver_cb_connect_ref != LUA_NOREF){ luaL_unref(L, LUA_REGISTRYINDEX, tcpserver_cb_connect_ref); tcpserver_cb_connect_ref = LUA_NOREF; } int n = lua_gettop(L); skt = nud; do{ if(isserver && skt == NULL){ if(socket[i] != LUA_NOREF){ // there is client socket exists lua_rawgeti(L, LUA_REGISTRYINDEX, socket[i]); // get the referenced user_data to stack top #if 0 socket[i] = LUA_NOREF; socket_num--; #endif // do this in net_server_disconnected i++; if(lua_isuserdata(L,-1)){ skt = lua_touserdata(L,-1); } else { lua_pop(L, 1); continue; } }else{ // skip LUA_NOREF i++; continue; } } if(skt==NULL){ NODE_DBG("userdata is nil.\n"); continue; } if(skt->pesp_conn) // disconnect the connection { if(skt->pesp_conn->type == ESPCONN_TCP) { #ifdef CLIENT_SSL_ENABLE if(skt->secure){ if(skt->pesp_conn->proto.tcp->remote_port || skt->pesp_conn->proto.tcp->local_port) espconn_secure_disconnect(skt->pesp_conn); } else #endif { if(skt->pesp_conn->proto.tcp->remote_port || skt->pesp_conn->proto.tcp->local_port) espconn_disconnect(skt->pesp_conn); } }else if(skt->pesp_conn->type == ESPCONN_UDP) { if(skt->pesp_conn->proto.tcp->remote_port || skt->pesp_conn->proto.tcp->local_port) espconn_delete(skt->pesp_conn); // a udp server/socket unref it self here. not in disconnect. if(LUA_NOREF!=skt->self_ref){ // for a udp self_ref is NOREF luaL_unref(L, LUA_REGISTRYINDEX, skt->self_ref); skt->self_ref = LUA_NOREF; // for a socket, now only var in lua is ref to the userdata } } } #if 0 // unref the self_ref if(LUA_NOREF!=skt->self_ref){ // for a server self_ref is NOREF luaL_unref(L, LUA_REGISTRYINDEX, skt->self_ref); skt->self_ref = LUA_NOREF; // for a socket, now only var in lua is ref to the userdata } #endif lua_settop(L, n); // reset the stack top skt = NULL; } while( isserver && i<MAX_SOCKET); #if 0 // unref the self_ref, for both socket and server if(LUA_NOREF!=nud->self_ref){ // for a server self_ref is NOREF luaL_unref(L, LUA_REGISTRYINDEX, nud->self_ref); nud->self_ref = LUA_NOREF; // now only var in lua is ref to the userdata } #endif return 0; }
// Lua: server/socket:send( string, function(sent) ) static int net_send( lua_State* L, const char* mt ) { // NODE_DBG("net_send is called.\n"); bool isserver = false; struct espconn *pesp_conn = NULL; lnet_userdata *nud; size_t l; nud = (lnet_userdata *)luaL_checkudata(L, 1, mt); luaL_argcheck(L, nud, 1, "Server/Socket expected"); if(nud==NULL){ NODE_DBG("userdata is nil.\n"); return 0; } if(nud->pesp_conn == NULL){ NODE_DBG("nud->pesp_conn is NULL.\n"); return 0; } pesp_conn = nud->pesp_conn; if (mt!=NULL && c_strcmp(mt, "net.server")==0) isserver = true; else if (mt!=NULL && c_strcmp(mt, "net.socket")==0) isserver = false; else { NODE_DBG("wrong metatable for net_send.\n"); return 0; } if(isserver && nud->pesp_conn->type == ESPCONN_TCP){ return luaL_error( L, "tcp server send not supported" ); } #if 0 char temp[20] = {0}; c_sprintf(temp, IPSTR, IP2STR( &(pesp_conn->proto.tcp->remote_ip) ) ); NODE_DBG("remote "); NODE_DBG(temp); NODE_DBG(":"); NODE_DBG("%d",pesp_conn->proto.tcp->remote_port); NODE_DBG(" sending data.\n"); #endif const char *payload = luaL_checklstring( L, 2, &l ); if (l>1460 || payload == NULL) return luaL_error( L, "need <1460 payload" ); if (lua_type(L, 3) == LUA_TFUNCTION || lua_type(L, 3) == LUA_TLIGHTFUNCTION){ lua_pushvalue(L, 3); // copy argument (func) to the top of stack if(nud->cb_send_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, nud->cb_send_ref); nud->cb_send_ref = luaL_ref(L, LUA_REGISTRYINDEX); } #ifdef CLIENT_SSL_ENABLE if(nud->secure) espconn_secure_sent(pesp_conn, (unsigned char *)payload, l); else #endif espconn_sent(pesp_conn, (unsigned char *)payload, l); return 0; }
luaTrajectory::~luaTrajectory(void) { luaL_unref( L, LUA_REGISTRYINDEX, ref); luaRegion::clear(); }
// static int net_close( lua_State* L, const char* mt ); // Lua: net.delete( socket/server ) // call close() first // server: disconnect server, unref everything // socket: unref everything static int net_delete( lua_State* L, const char* mt ) { NODE_DBG("net_delete is called.\n"); bool isserver = false; if (mt!=NULL && c_strcmp(mt, "net.server")==0) isserver = true; else if (mt!=NULL && c_strcmp(mt, "net.socket")==0) isserver = false; else { NODE_DBG("wrong metatable for net_delete.\n"); return 0; } // net_close( L, mt ); // close it first lnet_userdata *nud = (lnet_userdata *)luaL_checkudata(L, 1, mt); luaL_argcheck(L, nud, 1, "Server/Socket expected"); if(nud==NULL){ NODE_DBG("userdata is nil.\n"); return 0; } if(nud->pesp_conn){ // for client connected to tcp server, this should set NULL in disconnect cb nud->pesp_conn->reverse = NULL; if(!isserver) // socket is freed here { if(nud->pesp_conn->type == ESPCONN_UDP){ if(nud->pesp_conn->proto.udp) c_free(nud->pesp_conn->proto.udp); nud->pesp_conn->proto.udp = NULL; } else if (nud->pesp_conn->type == ESPCONN_TCP) { if(nud->pesp_conn->proto.tcp) c_free(nud->pesp_conn->proto.tcp); nud->pesp_conn->proto.tcp = NULL; } c_free(nud->pesp_conn); } nud->pesp_conn = NULL; // for socket, it will free this when disconnected } // free (unref) callback ref if(LUA_NOREF!=nud->cb_connect_ref){ luaL_unref(L, LUA_REGISTRYINDEX, nud->cb_connect_ref); nud->cb_connect_ref = LUA_NOREF; } if(LUA_NOREF!=nud->cb_reconnect_ref){ luaL_unref(L, LUA_REGISTRYINDEX, nud->cb_reconnect_ref); nud->cb_reconnect_ref = LUA_NOREF; } if(LUA_NOREF!=nud->cb_disconnect_ref){ luaL_unref(L, LUA_REGISTRYINDEX, nud->cb_disconnect_ref); nud->cb_disconnect_ref = LUA_NOREF; } if(LUA_NOREF!=nud->cb_receive_ref){ luaL_unref(L, LUA_REGISTRYINDEX, nud->cb_receive_ref); nud->cb_receive_ref = LUA_NOREF; } if(LUA_NOREF!=nud->cb_send_ref){ luaL_unref(L, LUA_REGISTRYINDEX, nud->cb_send_ref); nud->cb_send_ref = LUA_NOREF; } if(LUA_NOREF!=nud->cb_dns_found_ref){ luaL_unref(L, LUA_REGISTRYINDEX, nud->cb_dns_found_ref); nud->cb_dns_found_ref = LUA_NOREF; } lua_gc(gL, LUA_GCSTOP, 0); if(LUA_NOREF!=nud->self_ref){ luaL_unref(L, LUA_REGISTRYINDEX, nud->self_ref); nud->self_ref = LUA_NOREF; } lua_gc(gL, LUA_GCRESTART, 0); return 0; }
// initialise the JPLua system void JPLua_Init( void ) { #ifdef JPLUA size_t i = 0; #if defined(PROJECT_GAME) if ( !g_jplua.integer ) { #elif defined(PROJECT_CGAME) if ( !cg_jplua.integer ) { #endif return; } //Initialise and load base libraries memset( JPLua_Framework, -1, sizeof(JPLua_Framework) ); JPLua.state = luaL_newstate(); if ( !JPLua.state ) { //TODO: Fail gracefully return; } lua_atpanic( JPLua.state, JPLuaI_Error ); // Set the function called in a Lua error luaL_openlibs( JPLua.state ); luaopen_string( JPLua.state ); // Get rid of libraries we don't need lua_pushnil( JPLua.state ); lua_setglobal( JPLua.state, LUA_LOADLIBNAME ); // No need for the package library lua_pushnil( JPLua.state ); lua_setglobal( JPLua.state, LUA_IOLIBNAME ); // We use JKA engine facilities for file-handling // There are some stuff in the base library that we don't want lua_pushnil( JPLua.state ); lua_setglobal( JPLua.state, "dofile" ); lua_pushnil( JPLua.state ); lua_setglobal( JPLua.state, "loadfile" ); lua_pushnil( JPLua.state ); lua_setglobal( JPLua.state, "load" ); lua_pushnil( JPLua.state ); lua_setglobal( JPLua.state, "loadstring" ); // Some libraries we want, but not certain elements in them lua_getglobal( JPLua.state, LUA_OSLIBNAME ); // The OS library has dangerous access to the system, remove some parts of it lua_pushstring( JPLua.state, "execute" ); lua_pushnil( JPLua.state ); lua_settable( JPLua.state, -3 ); lua_pushstring( JPLua.state, "exit" ); lua_pushnil( JPLua.state ); lua_settable( JPLua.state, -3 ); lua_pushstring( JPLua.state, "remove" ); lua_pushnil( JPLua.state ); lua_settable( JPLua.state, -3 ); lua_pushstring( JPLua.state, "rename" ); lua_pushnil( JPLua.state ); lua_settable( JPLua.state, -3 ); lua_pushstring( JPLua.state, "setlocale" ); lua_pushnil( JPLua.state ); lua_settable( JPLua.state, -3 ); lua_pushstring( JPLua.state, "tmpname" ); lua_pushnil( JPLua.state ); lua_settable( JPLua.state, -3 ); lua_pop( JPLua.state, 1 ); // Redefine global functions lua_pushcclosure( JPLua.state, JPLua_Export_Print, 0 ); lua_setglobal( JPLua.state, "print" ); lua_pushcclosure( JPLua.state, JPLua_Export_Require, 0 ); lua_setglobal( JPLua.state, "require" ); for ( i = 0; i < cimportsSize; i++ ) lua_register( JPLua.state, JPLua_CImports[i].name, JPLua_CImports[i].function ); // Register our classes JPLua_Register_Player( JPLua.state ); JPLua_Register_Entity(JPLua.state); #ifdef PROJECT_CGAME JPLua_Register_Server( JPLua.state ); #endif JPLua_Register_Cvar( JPLua.state ); JPLua_Register_Logger( JPLua.state ); JPLua_Register_Serialiser( JPLua.state ); JPLua_Register_Vector( JPLua.state ); JPLua_Register_File( JPLua.state ); #ifdef PROJECT_GAME JPLua_Register_MySQL(JPLua.state); JPLua_Register_SQLite(JPLua.state); #endif // -- FRAMEWORK INITIALISATION begin lua_getglobal( JPLua.state, "tostring" ); JPLua_Framework[JPLUA_FRAMEWORK_TOSTRING] = luaL_ref( JPLua.state, LUA_REGISTRYINDEX ); lua_getglobal( JPLua.state, "pairs" ); JPLua_Framework[JPLUA_FRAMEWORK_PAIRS] = luaL_ref( JPLua.state, LUA_REGISTRYINDEX ); for ( i = 0; i < JPLUA_FRAMEWORK_MAX; i++ ) { if ( JPLua_Framework[i] < 0 ) Com_Error( ERR_FATAL, "FATAL ERROR: Could not properly initialize the JPLua framework!\n" ); } // -- FRAMEWORK INITIALISATION end //Call our base scripts JPLua_PostInit( JPLua.state ); #endif } void JPLua_Shutdown( void ) { #ifdef JPLUA if ( JPLua.state ) { jplua_plugin_t *nextPlugin = JPLua.plugins; JPLua_Event_Shutdown(); JPLua.currentPlugin = JPLua.plugins; while ( nextPlugin ) { for (int i = JPLUA_EVENT_UNLOAD; i < JPLUA_EVENT_MAX; i++){ if (JPLua.currentPlugin->eventListeners[i]) { luaL_unref(JPLua.state, LUA_REGISTRYINDEX, JPLua.currentPlugin->eventListeners[i]); } } luaL_unref( JPLua.state, LUA_REGISTRYINDEX, JPLua.currentPlugin->handle ); nextPlugin = JPLua.currentPlugin->next; free( JPLua.currentPlugin ); JPLua.currentPlugin = nextPlugin; } #ifdef PROJECT_GAME for (auto& row : jplua_client_commands){ luaL_unref(JPLua.state, LUA_REGISTRYINDEX, row.second); } jplua_client_commands.clear(); #elif defined PROJECT_CGAME for (auto& row : jplua_console_commands){ luaL_unref(JPLua.state, LUA_REGISTRYINDEX, row.second); } jplua_console_commands.clear(); #endif for (auto& row : jplua_server_commands){ luaL_unref(JPLua.state, LUA_REGISTRYINDEX, row.second); } jplua_server_commands.clear(); JPLua.plugins = JPLua.currentPlugin = NULL; lua_close( JPLua.state ); JPLua.state = NULL; JPLua.initialised = qfalse; } #endif }
// Hyper as in Hyperactive, Jk, its Hypersniper. void LuaEngineMgr::HyperCallFunction(const char * FuncName, int ref) { CREATE_L_PTR; string sFuncName = string(FuncName); char *copy = strdup(FuncName); char *token = strtok(copy, ".:"); int top = 1; bool colon = false; //REMEMBER: top is always 1 lua_settop(L, 0); //stack should be empty if (strpbrk(FuncName, ".:") == NULL ) //stack: empty lua_getglobal(L, FuncName); //stack: function else { lua_getglobal(L, "_G"); //start out with the global table. //stack: _G while (token != NULL) { lua_getfield(L, -1, token); //get the (hopefully) table/func //stack: _G, subtable/func/nil if ((int)sFuncName.find(token)-1 > 0) //if it isn't the first token { if (sFuncName.at(sFuncName.find(token)-1) == ':') colon = true; } if (lua_isfunction(L, -1) && !lua_iscfunction(L, -1)) //if it's a Lua function //stack: _G/subt, func { if (colon) //stack: subt, func { lua_pushvalue(L, -2); //make the table the first arg //stack: subt, func, subt lua_remove(L, top); //stack: func, subt } else lua_replace(L, top); //stack: func break; //we don't need anything else } else if(lua_istable(L, -1) ) //stack: _G/subt, subtable { token = strtok(NULL, ".:"); //stack: _G/subt, subtable lua_replace(L, top); //stack: subtable } } } lua_rawgeti(L, LUA_REGISTRYINDEX, ref); lua_State * M = lua_tothread(L, -1); //repeats, args int thread = lua_gettop(L); int repeats = luaL_checkinteger(M, 1); //repeats, args int nargs = lua_gettop(M)-1; if (nargs != 0) //if we HAVE args... { for (int i = 2; i <= nargs+1; i++) { lua_pushvalue(M, i); } lua_xmove(M, L, nargs); } if(repeats != 0) { if (--repeats == 0) //free stuff, then { free((void*)FuncName); luaL_unref(L, LUA_REGISTRYINDEX, ref); hash_map<int, EventInfoHolder*>::iterator itr = g_luaMgr.m_registeredTimedEvents.find(ref); g_luaMgr.m_registeredTimedEvents.erase(itr); } else { lua_remove(M, 1); //args lua_pushinteger(M, repeats); //args, repeats lua_insert(M, 1); //repeats, args } } lua_remove(L, thread); //now we can remove the thread object int r = lua_pcall(L, nargs+(colon ? 1 : 0), 0, 0); if (r) report(L); free((void*)copy); lua_settop(L, 0); }
void L_unref( int table_index, int ref ) { luaL_unref( m_lua.get(), table_index, ref ); }
void LUA_DeregisterObject(lua_State* L, int id) { luaL_unref(L, LUA_REGISTRYINDEX, id); }
void L_unref( int ref ) { luaL_unref( m_lua.get(), LUA_REGISTRYINDEX, ref ); }
/**\brief Mission Destructor */ Mission::~Mission() { luaL_unref(L, LUA_REGISTRYINDEX, tableReference); }
gboolean rspamadm_execute_lua_ucl_subr (gpointer pL, gint argc, gchar **argv, const ucl_object_t *res, const gchar *script) { lua_State *L = pL; gint err_idx, cb_idx, i, ret; GString *tb; g_assert (script != NULL); g_assert (res != NULL); g_assert (L != NULL); if (luaL_dostring (L, script) != 0) { msg_err ("cannot execute lua script: %s", lua_tostring (L, -1)); return FALSE; } else { if (lua_type (L, -1) == LUA_TFUNCTION) { cb_idx = luaL_ref (L, LUA_REGISTRYINDEX); } else { msg_err ("lua script must return " "function and not %s", lua_typename (L, lua_type (L, -1))); return FALSE; } } lua_pushcfunction (L, &rspamd_lua_traceback); err_idx = lua_gettop (L); /* Push function */ lua_rawgeti (L, LUA_REGISTRYINDEX, cb_idx); /* Push argv */ lua_newtable (L); for (i = 0; i < argc; i ++) { lua_pushstring (L, argv[i]); lua_rawseti (L, -2, i + 1); } /* Push results */ ucl_object_push_lua (L, res, TRUE); if ((ret = lua_pcall (L, 2, 0, err_idx)) != 0) { tb = lua_touserdata (L, -1); msg_err ("call to adm lua script failed (%d): %v", ret, tb); if (tb) { g_string_free (tb, TRUE); } lua_pop (L, 2); return FALSE; } /* error function */ lua_pop (L, 1); luaL_unref (L, LUA_REGISTRYINDEX, cb_idx); return TRUE; }
static void luv_check_callback(lua_State* L, luv_handle_t* data, luv_callback_id id, int index) { luaL_checktype(L, index, LUA_TFUNCTION); luaL_unref(L, LUA_REGISTRYINDEX, data->callbacks[id]); lua_pushvalue(L, index); data->callbacks[id] = luaL_ref(L, LUA_REGISTRYINDEX); }
static void ngx_http_lua_timer_handler(ngx_event_t *ev) { int n; lua_State *L; ngx_int_t rc; ngx_connection_t *c = NULL; ngx_http_request_t *r = NULL; ngx_http_lua_ctx_t *ctx; ngx_http_cleanup_t *cln; ngx_pool_cleanup_t *pcln; ngx_http_lua_timer_ctx_t tctx; ngx_http_lua_main_conf_t *lmcf; ngx_http_core_loc_conf_t *clcf; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, "lua ngx.timer expired"); ngx_memcpy(&tctx, ev->data, sizeof(ngx_http_lua_timer_ctx_t)); ngx_free(ev); ev = NULL; lmcf = tctx.lmcf; lmcf->pending_timers--; if (lmcf->running_timers >= lmcf->max_running_timers) { ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "%i lua_max_running_timers are not enough", lmcf->max_running_timers); goto failed; } c = ngx_http_lua_create_fake_connection(tctx.pool); if (c == NULL) { goto failed; } c->log->handler = ngx_http_lua_log_timer_error; c->log->data = c; c->listening = tctx.listening; c->addr_text = tctx.client_addr_text; r = ngx_http_lua_create_fake_request(c); if (r == NULL) { goto failed; } r->main_conf = tctx.main_conf; r->srv_conf = tctx.srv_conf; r->loc_conf = tctx.loc_conf; clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); #if defined(nginx_version) && nginx_version >= 1003014 ngx_http_set_connection_log(r->connection, clcf->error_log); #else c->log->file = clcf->error_log->file; if (!(c->log->log_level & NGX_LOG_DEBUG_CONNECTION)) { c->log->log_level = clcf->error_log->log_level; } #endif dd("lmcf: %p", lmcf); ctx = ngx_http_lua_create_ctx(r); if (ctx == NULL) { goto failed; } if (tctx.vm_state) { ctx->vm_state = tctx.vm_state; pcln = ngx_pool_cleanup_add(r->pool, 0); if (pcln == NULL) { goto failed; } pcln->handler = ngx_http_lua_cleanup_vm; pcln->data = tctx.vm_state; } ctx->cur_co_ctx = &ctx->entry_co_ctx; L = ngx_http_lua_get_lua_vm(r, ctx); cln = ngx_http_cleanup_add(r, 0); if (cln == NULL) { goto failed; } cln->handler = ngx_http_lua_request_cleanup_handler; cln->data = ctx; ctx->cleanup = &cln->handler; ctx->entered_content_phase = 1; ctx->context = NGX_HTTP_LUA_CONTEXT_TIMER; r->read_event_handler = ngx_http_block_reading; ctx->cur_co_ctx->co_ref = tctx.co_ref; ctx->cur_co_ctx->co = tctx.co; ctx->cur_co_ctx->co_status = NGX_HTTP_LUA_CO_RUNNING; dd("r connection: %p, log %p", r->connection, r->connection->log); /* save the request in coroutine globals table */ ngx_http_lua_set_req(tctx.co, r); lmcf->running_timers++; lua_pushboolean(tctx.co, tctx.premature); n = lua_gettop(tctx.co); if (n > 2) { lua_insert(tctx.co, 2); } #ifdef NGX_LUA_USE_ASSERT ctx->cur_co_ctx->co_top = 1; #endif rc = ngx_http_lua_run_thread(L, r, ctx, n - 1); dd("timer lua run thread: %d", (int) rc); if (rc == NGX_ERROR || rc >= NGX_OK) { /* do nothing */ } else if (rc == NGX_AGAIN) { rc = ngx_http_lua_content_run_posted_threads(L, r, ctx, 0); } else if (rc == NGX_DONE) { rc = ngx_http_lua_content_run_posted_threads(L, r, ctx, 1); } else { rc = NGX_OK; } ngx_http_lua_finalize_request(r, rc); return; failed: if (tctx.co_ref && tctx.co) { lua_pushlightuserdata(tctx.co, &ngx_http_lua_coroutines_key); lua_rawget(tctx.co, LUA_REGISTRYINDEX); luaL_unref(tctx.co, -1, tctx.co_ref); lua_settop(tctx.co, 0); } if (tctx.vm_state) { ngx_http_lua_cleanup_vm(tctx.vm_state); } if (c) { ngx_http_lua_close_fake_connection(c); } else if (tctx.pool) { ngx_destroy_pool(tctx.pool); } }
void NzLuaInstance::DestroyReference(int ref) { luaL_unref(m_state, LUA_REGISTRYINDEX, ref); }
static int ngx_http_lua_ngx_timer_at(lua_State *L) { int nargs, co_ref; u_char *p; lua_State *vm; /* the main thread */ lua_State *co; ngx_msec_t delay; ngx_event_t *ev; ngx_http_request_t *r; ngx_connection_t *saved_c = NULL; ngx_http_lua_ctx_t *ctx; #if 0 ngx_http_connection_t *hc; #endif ngx_http_lua_timer_ctx_t *tctx = NULL; ngx_http_lua_main_conf_t *lmcf; #if 0 ngx_http_core_main_conf_t *cmcf; #endif nargs = lua_gettop(L); if (nargs < 2) { return luaL_error(L, "expecting at least 2 arguments but got %d", nargs); } delay = (ngx_msec_t) (luaL_checknumber(L, 1) * 1000); luaL_argcheck(L, lua_isfunction(L, 2) && !lua_iscfunction(L, 2), 2, "Lua function expected"); r = ngx_http_lua_get_req(L); if (r == NULL) { return luaL_error(L, "no request"); } ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); if (ngx_exiting && delay > 0) { lua_pushnil(L); lua_pushliteral(L, "process exiting"); return 2; } lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module); if (lmcf->pending_timers >= lmcf->max_pending_timers) { lua_pushnil(L); lua_pushliteral(L, "too many pending timers"); return 2; } if (lmcf->watcher == NULL) { /* create the watcher fake connection */ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, "lua creating fake watcher connection"); if (ngx_cycle->files) { saved_c = ngx_cycle->files[0]; } lmcf->watcher = ngx_get_connection(0, ngx_cycle->log); if (ngx_cycle->files) { ngx_cycle->files[0] = saved_c; } if (lmcf->watcher == NULL) { return luaL_error(L, "no memory"); } /* to work around the -1 check in ngx_worker_process_cycle: */ lmcf->watcher->fd = (ngx_socket_t) -2; lmcf->watcher->idle = 1; lmcf->watcher->read->handler = ngx_http_lua_abort_pending_timers; lmcf->watcher->data = lmcf; } vm = ngx_http_lua_get_lua_vm(r, ctx); co = lua_newthread(vm); /* L stack: time func [args] thread */ ngx_http_lua_probe_user_coroutine_create(r, L, co); lua_createtable(co, 0, 0); /* the new globals table */ /* co stack: global_tb */ lua_createtable(co, 0, 1); /* the metatable */ ngx_http_lua_get_globals_table(co); lua_setfield(co, -2, "__index"); lua_setmetatable(co, -2); /* co stack: global_tb */ ngx_http_lua_set_globals_table(co); /* co stack: <empty> */ dd("stack top: %d", lua_gettop(L)); lua_xmove(vm, L, 1); /* move coroutine from main thread to L */ /* L stack: time func [args] thread */ /* vm stack: empty */ lua_pushvalue(L, 2); /* copy entry function to top of L*/ /* L stack: time func [args] thread func */ lua_xmove(L, co, 1); /* move entry function from L to co */ /* L stack: time func [args] thread */ /* co stack: func */ ngx_http_lua_get_globals_table(co); lua_setfenv(co, -2); /* co stack: func */ lua_pushlightuserdata(L, &ngx_http_lua_coroutines_key); lua_rawget(L, LUA_REGISTRYINDEX); /* L stack: time func [args] thread corountines */ lua_pushvalue(L, -2); /* L stack: time func [args] thread coroutines thread */ co_ref = luaL_ref(L, -2); lua_pop(L, 1); /* L stack: time func [args] thread */ if (nargs > 2) { lua_pop(L, 1); /* L stack: time func [args] */ lua_xmove(L, co, nargs - 2); /* L stack: time func */ /* co stack: func [args] */ } p = ngx_alloc(sizeof(ngx_event_t) + sizeof(ngx_http_lua_timer_ctx_t), r->connection->log); if (p == NULL) { goto nomem; } ev = (ngx_event_t *) p; ngx_memzero(ev, sizeof(ngx_event_t)); p += sizeof(ngx_event_t); tctx = (ngx_http_lua_timer_ctx_t *) p; tctx->premature = 0; tctx->co_ref = co_ref; tctx->co = co; tctx->main_conf = r->main_conf; tctx->srv_conf = r->srv_conf; tctx->loc_conf = r->loc_conf; tctx->lmcf = lmcf; tctx->pool = ngx_create_pool(128, ngx_cycle->log); if (tctx->pool == NULL) { goto nomem; } if (r->connection) { tctx->listening = r->connection->listening; } else { tctx->listening = NULL; } if (r->connection->addr_text.len) { tctx->client_addr_text.data = ngx_palloc(tctx->pool, r->connection->addr_text.len); if (tctx->client_addr_text.data == NULL) { goto nomem; } ngx_memcpy(tctx->client_addr_text.data, r->connection->addr_text.data, r->connection->addr_text.len); tctx->client_addr_text.len = r->connection->addr_text.len; } else { tctx->client_addr_text.len = 0; tctx->client_addr_text.data = NULL; } if (ctx && ctx->vm_state) { tctx->vm_state = ctx->vm_state; tctx->vm_state->count++; } else { tctx->vm_state = NULL; } ev->handler = ngx_http_lua_timer_handler; ev->data = tctx; ev->log = ngx_cycle->log; lmcf->pending_timers++; ngx_add_timer(ev, delay); lua_pushinteger(L, 1); return 1; nomem: if (tctx && tctx->pool) { ngx_destroy_pool(tctx->pool); } lua_pushlightuserdata(L, &ngx_http_lua_coroutines_key); lua_rawget(L, LUA_REGISTRYINDEX); luaL_unref(L, -1, co_ref); return luaL_error(L, "no memory"); }
static QUVIcode run_parse_func(_quvi_llst_node_t n, _quvi_media_t m) { static const char *f = "parse"; _quvi_lua_script_t s; _quvi_t quvi; lua_State *l; QUVIcode rc; assert(n != NULL); assert(m != NULL); quvi = m->quvi; /* seterr macro needs this. */ l = quvi->lua; s = (_quvi_lua_script_t) n->data; rc = QUVI_OK; lua_getglobal(l, f); if (!lua_isfunction(l, -1)) { freprintf(&quvi->errmsg, "%s: `%s' function not found", s->path, f); return (QUVI_LUA); } lua_newtable(l); setfield_reg_userdata(l, USERDATA_QUVI_MEDIA_T, m); setfield_s(l, "requested_format", m->quvi->format); setfield_s(l, "page_url", m->page_url); setfield_s(l, "thumbnail_url", ""); setfield_s(l, "redirect_url", ""); setfield_s(l, "start_time", ""); setfield_n(l, "duration", 0); if (lua_pcall(l, 1, 1, 0)) { freprintf(&quvi->errmsg, "%s", lua_tostring(l, -1)); return (QUVI_LUA); } if (!lua_istable(l, -1)) { freprintf(&quvi->errmsg, "expected `%s' function return a table", f); return (QUVI_LUA); } freprintf(&m->redirect_url, "%s", getfield_s(l, "redirect_url", s, f)); if (strlen(m->redirect_url) == 0) { const int r = luaL_ref(l, LUA_REGISTRYINDEX); rc = run_lua_trim_fields_func(m, r); luaL_unref(l, LUA_REGISTRYINDEX, r); if (rc == QUVI_OK) { #define _wrap(n) \ do { freprintf(&m->n, "%s", getfield_s(l, #n, s, f)); } while (0) _wrap(thumbnail_url); _wrap(start_time); _wrap(host_id); _wrap(title); _wrap(id); #undef _wrap m->duration = getfield_n(l, "duration", s, f); rc = getfield_iter_table_s(l, "url", m, s, f); } } lua_pop(l, 1); return (rc); }
void LuaArgs::releaseF(lua_State *L, int ref) { luaL_unref(L, LUA_REGISTRYINDEX, ref); }
// Lua: server:listen( port, ip, function(con) ) // Lua: socket:connect( port, ip, function(con) ) static int net_start( lua_State* L, const char* mt ) { NODE_DBG("net_start is called.\n"); struct espconn *pesp_conn = NULL; lnet_userdata *nud; unsigned port; size_t il; bool isserver = false; ip_addr_t ipaddr; const char *domain; uint8_t stack = 1; if (mt!=NULL && c_strcmp(mt, "net.server")==0) isserver = true; else if (mt!=NULL && c_strcmp(mt, "net.socket")==0) isserver = false; else { NODE_DBG("wrong metatable for net_start.\n"); return 0; } nud = (lnet_userdata *)luaL_checkudata(L, stack, mt); luaL_argcheck(L, nud, stack, "Server/Socket expected"); stack++; if(nud==NULL){ NODE_DBG("userdata is nil.\n"); return 0; } pesp_conn = nud->pesp_conn; port = luaL_checkinteger( L, stack ); stack++; if( pesp_conn->type == ESPCONN_TCP ) { if(isserver) pesp_conn->proto.tcp->local_port = port; else{ pesp_conn->proto.tcp->remote_port = port; pesp_conn->proto.tcp->local_port = espconn_port(); } NODE_DBG("TCP port is set: %d.\n", port); } else if (pesp_conn->type == ESPCONN_UDP) { if(isserver) pesp_conn->proto.udp->local_port = port; else{ pesp_conn->proto.udp->remote_port = port; pesp_conn->proto.udp->local_port = espconn_port(); } NODE_DBG("UDP port is set: %d.\n", port); } if( lua_isstring(L,stack) ) // deal with the domain string { domain = luaL_checklstring( L, stack, &il ); stack++; if (domain == NULL) { if(isserver) domain = "0.0.0.0"; else domain = "127.0.0.1"; } ipaddr.addr = ipaddr_addr(domain); if( pesp_conn->type == ESPCONN_TCP ) { if(isserver) c_memcpy(pesp_conn->proto.tcp->local_ip, &ipaddr.addr, 4); else c_memcpy(pesp_conn->proto.tcp->remote_ip, &ipaddr.addr, 4); NODE_DBG("TCP ip is set: "); NODE_DBG(IPSTR, IP2STR(&ipaddr.addr)); NODE_DBG("\n"); } else if (pesp_conn->type == ESPCONN_UDP) { if(isserver) c_memcpy(pesp_conn->proto.udp->local_ip, &ipaddr.addr, 4); else c_memcpy(pesp_conn->proto.udp->remote_ip, &ipaddr.addr, 4); NODE_DBG("UDP ip is set: "); NODE_DBG(IPSTR, IP2STR(&ipaddr.addr)); NODE_DBG("\n"); } } // call back function when a connection is obtained, tcp only if ( pesp_conn->type == ESPCONN_TCP ) { if (lua_type(L, stack) == LUA_TFUNCTION || lua_type(L, stack) == LUA_TLIGHTFUNCTION){ lua_pushvalue(L, stack); // copy argument (func) to the top of stack if(isserver) // for tcp server connected callback { if(tcpserver_cb_connect_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, tcpserver_cb_connect_ref); tcpserver_cb_connect_ref = luaL_ref(L, LUA_REGISTRYINDEX); } else { if(nud->cb_connect_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, nud->cb_connect_ref); nud->cb_connect_ref = luaL_ref(L, LUA_REGISTRYINDEX); } } } if(!isserver || pesp_conn->type == ESPCONN_UDP){ // self_ref is only needed by socket userdata, or udp server lua_pushvalue(L, 1); // copy to the top of stack if(nud->self_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, nud->self_ref); nud->self_ref = luaL_ref(L, LUA_REGISTRYINDEX); } if( pesp_conn->type == ESPCONN_TCP ) { if(isserver){ // no secure server support for now espconn_regist_connectcb(pesp_conn, net_server_connected); // tcp server, SSL is not supported #ifdef CLIENT_SSL_ENABLE // if(nud->secure) // espconn_secure_accept(pesp_conn); // else #endif espconn_accept(pesp_conn); // if it's a server, no need to dns. espconn_regist_time(pesp_conn, tcp_server_timeover, 0); } else{ espconn_regist_connectcb(pesp_conn, net_socket_connected); espconn_regist_reconcb(pesp_conn, net_socket_reconnected); #ifdef CLIENT_SSL_ENABLE if(nud->secure){ if(pesp_conn->proto.tcp->remote_port || pesp_conn->proto.tcp->local_port) espconn_secure_disconnect(pesp_conn); // espconn_secure_connect(pesp_conn); } else #endif { if(pesp_conn->proto.tcp->remote_port || pesp_conn->proto.tcp->local_port) espconn_disconnect(pesp_conn); // espconn_connect(pesp_conn); } } } else if (pesp_conn->type == ESPCONN_UDP) { espconn_regist_recvcb(pesp_conn, net_socket_received); espconn_regist_sentcb(pesp_conn, net_socket_sent); if(pesp_conn->proto.tcp->remote_port || pesp_conn->proto.tcp->local_port) espconn_delete(pesp_conn); if(isserver) espconn_create(pesp_conn); // if it's a server, no need to dns. } if(!isserver){ if((ipaddr.addr == IPADDR_NONE) && (c_memcmp(domain,"255.255.255.255",16) != 0)) { host_ip.addr = 0; dns_reconn_count = 0; if(ESPCONN_OK == espconn_gethostbyname(pesp_conn, domain, &host_ip, socket_dns_found)){ socket_dns_found(domain, &host_ip, pesp_conn); // ip is returned in host_ip. } } else { socket_connect(pesp_conn); } } return 0; }
Value::~Value() { if (m_state != nullptr) luaL_unref(m_state, LUA_REGISTRYINDEX, m_ref); }
// Lua: socket/udpserver:on( "method", function(s) ) static int net_on( lua_State* L, const char* mt ) { NODE_DBG("net_on is called.\n"); bool isserver = false; lnet_userdata *nud; size_t sl; nud = (lnet_userdata *)luaL_checkudata(L, 1, mt); luaL_argcheck(L, nud, 1, "Server/Socket expected"); if(nud==NULL){ NODE_DBG("userdata is nil.\n"); return 0; } if (mt!=NULL && c_strcmp(mt, "net.server")==0) isserver = true; else if (mt!=NULL && c_strcmp(mt, "net.socket")==0) isserver = false; else { NODE_DBG("wrong metatable for net_on.\n"); return 0; } const char *method = luaL_checklstring( L, 2, &sl ); if (method == NULL) return luaL_error( L, "wrong arg type" ); luaL_checkanyfunction(L, 3); lua_pushvalue(L, 3); // copy argument (func) to the top of stack if(!isserver && nud->pesp_conn->type == ESPCONN_TCP && sl == 10 && c_strcmp(method, "connection") == 0){ if(nud->cb_connect_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, nud->cb_connect_ref); nud->cb_connect_ref = luaL_ref(L, LUA_REGISTRYINDEX); }else if(!isserver && nud->pesp_conn->type == ESPCONN_TCP && sl == 12 && c_strcmp(method, "reconnection") == 0){ if(nud->cb_reconnect_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, nud->cb_reconnect_ref); nud->cb_reconnect_ref = luaL_ref(L, LUA_REGISTRYINDEX); }else if(!isserver && nud->pesp_conn->type == ESPCONN_TCP && sl == 13 && c_strcmp(method, "disconnection") == 0){ if(nud->cb_disconnect_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, nud->cb_disconnect_ref); nud->cb_disconnect_ref = luaL_ref(L, LUA_REGISTRYINDEX); }else if((!isserver || nud->pesp_conn->type == ESPCONN_UDP) && sl == 7 && c_strcmp(method, "receive") == 0){ if(nud->cb_receive_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, nud->cb_receive_ref); nud->cb_receive_ref = luaL_ref(L, LUA_REGISTRYINDEX); }else if((!isserver || nud->pesp_conn->type == ESPCONN_UDP) && sl == 4 && c_strcmp(method, "sent") == 0){ if(nud->cb_send_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, nud->cb_send_ref); nud->cb_send_ref = luaL_ref(L, LUA_REGISTRYINDEX); }else if(!isserver && nud->pesp_conn->type == ESPCONN_TCP && sl == 3 && c_strcmp(method, "dns") == 0){ if(nud->cb_dns_found_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, nud->cb_dns_found_ref); nud->cb_dns_found_ref = luaL_ref(L, LUA_REGISTRYINDEX); }else{ lua_pop(L, 1); return luaL_error( L, "method not supported" ); } return 0; }
/**-------------------------------------------------------------------------- * Handle outgoing T.Http.Connection into it's socket. * \param L lua Virtual Machine. * \lparam userdata struct t_htp_con. * \param pointer to the buffer to read from(already positioned). * \lreturn value from the buffer a packers position according to packer format. * \return int # of values pushed onto the stack. * -------------------------------------------------------------------------*/ int t_htp_con_rsp( lua_State *L ) { struct t_htp_con *c = t_htp_con_check_ud( L, 1, 1 ); size_t snt; const char *b; struct t_htp_buf *buf = c->buf_head; struct t_htp_str *str; // TODO: test for NULL // get tail buffer turn into char * array lua_rawgeti( L, LUA_REGISTRYINDEX, buf->bR ); b = lua_tostring( L, -1 ); // fetch the currently active stream for this buffer lua_rawgeti( L, LUA_REGISTRYINDEX, buf->sR ); str = t_htp_str_check_ud( L, -1, 1 ); //printf( "Send ResponseChunk: %s\n", b ); snt = t_net_tcp_send( L, c->sck, &(b[ buf->sl ]), buf->bl - buf->sl ); buf->sl += snt; // How much of current buffer is sent -> adjustment str->rsSl += snt; // How much of current stream is sent -> adjustment //printf( "%zu %zu -- %u %u\n", buf->sl, buf->bl, // buf->sl==buf->bl, buf->sl!=buf->bl ); if (buf->bl == buf->sl) // current buffer is sent completly { if ( buf->last ) { //printf( "EndOfStream\n" ); lua_pushcfunction( L, lt_htp_str__gc ); lua_rawgeti( L, LUA_REGISTRYINDEX, buf->sR ); luaL_unref( L, LUA_REGISTRYINDEX, buf->sR ); // unref stream for gc lua_call( L, 1, 0 ); } // free current buffer and go backwards in linked list luaL_unref( L, LUA_REGISTRYINDEX, buf->bR ); // unref string for gc c->buf_head = buf->nxt; free( buf ); // TODO: If there is no kpAlv discard connection // If kpAlv and the buffers are empty, set up a timer to discard // on kpAlv timeout if (NULL == c->buf_head) // current connection has no buffers left { printf( "remove "T_HTP_CON_TYPE" from Loop\n" ); // remove this connections socket from evLoop t_ael_removehandle_impl( c->srv->ael, c->sck->fd, T_AEL_WR ); c->srv->ael->fd_set[ c->sck->fd ]->t = T_AEL_RD; // done with current the stream has overall if ( T_HTP_STR_FINISH == str->state || str->rsSl == str->rsBl) { if (! c->kpAlv) { lua_pushcfunction( L, lt_htp_con__gc ); lua_pushvalue( L, 1 ); lua_call( L, 1, 0 ); return 1; } } } } return 1; }
static int setScript(lua_State* L) { BarrierData* barrier = static_cast<BarrierData*>(lua_touserdata(L, 1)); luaL_unref(L, LUA_REGISTRYINDEX, barrier->GetScriptReference()); barrier->SetScriptReference(luaL_ref(L, LUA_REGISTRYINDEX)); return 0; }
static void lzn_unref(lua_State *L, int *ref) { luaL_unref(L, LUA_REGISTRYINDEX, *ref); *ref = LUA_NOREF; }
/// destructor luaNeighborhood::~luaNeighborhood( void ) { luaL_unref( L, LUA_REGISTRYINDEX, ref); }
LuaScript::LuaThread::~LuaThread() { LuaScript *luaScript = static_cast<LuaScript*>(mScript); luaL_unref(luaScript->mRootState, LUA_REGISTRYINDEX, mRef); }
/* Unrefer mib search handler */ void mib_handler_unref(int handler) { lua_State *L = mib_lua_state; luaL_unref(L, LUA_ENVIRONINDEX, handler); }
void AnyRef::pop(lua_State* L) { if (this->L) luaL_unref(this->L, LUA_REGISTRYINDEX, ref); this->L = L; ref = luaL_ref(L, LUA_REGISTRYINDEX); }