diff --git a/src/lua/init.cc b/src/lua/init.cc index cab1410d5d5c13490e8204749756b7466ca81e68..667cfbc314d010f6ec51eaabe6726bd3876c381a 100644 --- a/src/lua/init.cc +++ b/src/lua/init.cc @@ -60,7 +60,14 @@ extern "C" { #include <readline/readline.h> #include <readline/history.h> +/** + * The single Lua state of the transaction processor (tx) thread. + */ struct lua_State *tarantool_L; +/** + * The fiber running the startup Lua script + */ +struct fiber *script_fiber; /* contents of src/lua/ files */ extern char uuid_lua[], @@ -432,19 +439,30 @@ tarantool_lua_run_script(char *path) * To work this problem around we must run init script in * a separate fiber. */ - struct fiber *loader = fiber_new(title, run_script); - fiber_call(loader, tarantool_L, path); + script_fiber = fiber_new(title, run_script); + fiber_call(script_fiber, tarantool_L, path); /* * Run an auxiliary event loop to re-schedule run_script fiber. * When this fiber finishes, it will call ev_break to stop the loop. */ ev_run(loop(), 0); + /* The fiber running the startup script has ended. */ + script_fiber = NULL; } void tarantool_lua_free() { + /* + * Some part of the start script panicked, and called + * exit(). The call stack in this case leads us back to + * luaL_call() in run_script(). Trying to free a Lua state + * from within luaL_call() is not the smartest idea (@sa + * gh-612). + */ + if (script_fiber) + return; /* * Got to be done prior to anything else, since GC * handlers can refer to other subsystems (e.g. fibers).