Browse Source

Add per worker lua_State

personal/stbuehler/wip
Stefan Bühler 13 years ago
parent
commit
d9228f3ef0
  1. 4
      include/lighttpd/config_lua.h
  2. 2
      include/lighttpd/core_lua.h
  3. 4
      include/lighttpd/worker.h
  4. 26
      src/main/config_lua.c
  5. 2
      src/main/config_parser.rl
  6. 6
      src/main/core_lua.c
  7. 2
      src/main/lighttpd.c
  8. 2
      src/main/server.c
  9. 19
      src/main/worker.c

4
include/lighttpd/config_lua.h

@ -3,6 +3,8 @@
#include <lighttpd/base.h>
LI_API gboolean li_config_lua_load(liServer *srv, const gchar *filename, liAction **pact);
#include <lualib.h>
LI_API gboolean li_config_lua_load(lua_State *L, liServer *srv, const gchar *filename, liAction **pact, gboolean allow_setup);
#endif

2
include/lighttpd/core_lua.h

@ -53,7 +53,7 @@ LI_API int li_lua_push_vrequest(lua_State *L, liVRequest *vr);
*/
LI_API int li_lua_metatable_index(lua_State *L);
LI_API void li_lua_init(liServer *srv, lua_State *L);
LI_API void li_lua_init(lua_State* L, liServer* srv, liWorker* wrk);
LI_API int li_lua_push_traceback(lua_State *L, int narg);

4
include/lighttpd/worker.h

@ -5,6 +5,8 @@
#error Please include <lighttpd/base.h> instead of this file
#endif
struct lua_State;
typedef struct liStatistics liStatistics;
struct liStatistics {
guint64 bytes_out; /** bytes transfered, outgoing */
@ -51,6 +53,8 @@ struct liWorker {
GThread *thread; /* managed by server.c */
guint ndx; /* worker index */
struct lua_State *L; /** NULL if compiled without Lua */
struct ev_loop *loop;
ev_prepare loop_prepare;
ev_check loop_check;

26
src/main/config_lua.c

@ -4,7 +4,7 @@
#include <lighttpd/value_lua.h>
#include <lighttpd/actions_lua.h>
# include <lighttpd/core_lua.h>
#include <lighttpd/core_lua.h>
#include <lualib.h>
#include <lauxlib.h>
@ -183,14 +183,14 @@ static int handle_server_setup(liServer *srv, lua_State *L, gpointer _ss) {
return 0;
}
gboolean li_config_lua_load(liServer *srv, const gchar *filename, liAction **pact) {
lua_State *L = srv->L;
gboolean li_config_lua_load(lua_State *L, liServer *srv, const gchar *filename, liAction **pact, gboolean allow_setup) {
int errfunc;
int lua_stack_top;
gboolean dolock = (L == srv->L);
*pact = NULL;
li_lua_lock(srv);
if (dolock) li_lua_lock(srv);
lua_stack_top = lua_gettop(L);
@ -203,8 +203,10 @@ gboolean li_config_lua_load(liServer *srv, const gchar *filename, liAction **pac
DEBUG(srv, "Loaded config script '%s'", filename);
publish_str_hash(srv, L, srv->setups, handle_server_setup);
lua_setfield(L, LUA_GLOBALSINDEX, "setup");
if (allow_setup) {
publish_str_hash(srv, L, srv->setups, handle_server_setup);
lua_setfield(L, LUA_GLOBALSINDEX, "setup");
}
publish_str_hash(srv, L, srv->actions, handle_server_action);
lua_setfield(L, LUA_GLOBALSINDEX, "action");
@ -214,6 +216,16 @@ gboolean li_config_lua_load(liServer *srv, const gchar *filename, liAction **pac
errfunc = li_lua_push_traceback(L, 0);
if (lua_pcall(L, 0, 1, errfunc)) {
ERROR(srv, "lua_pcall(): %s", lua_tostring(L, -1));
/* cleanup stack */
if (lua_stack_top > lua_gettop(L)) {
lua_pop(L, lua_gettop(L) - lua_stack_top);
}
li_lua_restore_globals(L);
if (dolock) li_lua_unlock(srv);
return FALSE;
}
lua_remove(L, errfunc);
@ -239,7 +251,7 @@ gboolean li_config_lua_load(liServer *srv, const gchar *filename, liAction **pac
li_lua_restore_globals(L);
li_lua_unlock(srv);
if (dolock) li_lua_unlock(srv);
return TRUE;
}

2
src/main/config_parser.rl

@ -746,7 +746,7 @@
return FALSE;
}
if (!li_config_lua_load(srv, val->data.string->str, &a)) {
if (!li_config_lua_load(srv->L, srv, val->data.string->str, &a, TRUE)) {
ERROR(srv, "include_lua '%s' failed", val->data.string->str);
li_value_free(name);
li_value_free(val);

6
src/main/core_lua.c

@ -137,7 +137,7 @@ static void lua_push_constants(lua_State *L, int ndx) {
lua_setfield(L, ndx, "HANDLER_ERROR");
}
void li_lua_init(liServer *srv, lua_State *L) {
void li_lua_init(lua_State *L, liServer *srv, liWorker *wrk) {
li_lua_init_chunk_mt(L);
li_lua_init_connection_mt(L);
li_lua_init_environment_mt(L);
@ -151,6 +151,10 @@ void li_lua_init(liServer *srv, lua_State *L) {
/* prefer closure, but just in case */
lua_pushlightuserdata(L, srv);
lua_setfield(L, LUA_REGISTRYINDEX, "lighty.srv");
if (NULL != wrk) {
lua_pushlightuserdata(L, wrk);
lua_setfield(L, LUA_REGISTRYINDEX, "lighty.wrk");
}
lua_newtable(L); /* lighty. */

2
src/main/lighttpd.c

@ -132,7 +132,7 @@ int main(int argc, char *argv[]) {
}
else {
#ifdef HAVE_LUA_H
li_config_lua_load(srv, config_path, &srv->mainaction);
li_config_lua_load(srv->L, srv, config_path, &srv->mainaction, TRUE);
/* lua config frontend */
#else
g_print("lua config frontend not available\n");

2
src/main/server.c

@ -93,7 +93,7 @@ liServer* li_server_new(const gchar *module_dir) {
#ifdef HAVE_LUA_H
srv->L = luaL_newstate();
luaL_openlibs(srv->L);
li_lua_init(srv, srv->L);
li_lua_init(srv->L, srv, NULL);
srv->lualock = g_mutex_new();
#else

19
src/main/worker.c

@ -3,6 +3,12 @@
#include <lighttpd/plugin_core.h>
#ifdef HAVE_LUA_H
# include <lighttpd/core_lua.h>
# include <lualib.h>
# include <lauxlib.h>
#endif
#include <sched.h>
static liConnection* worker_con_get(liWorker *wrk);
@ -365,6 +371,14 @@ liWorker* li_worker_new(liServer *srv, struct ev_loop *loop) {
wrk->srv = srv;
wrk->loop = loop;
#ifdef HAVE_LUA_H
wrk->L = luaL_newstate();
luaL_openlibs(wrk->L);
li_lua_init(wrk->L, srv, wrk);
#else
wrk->L = NULL;
#endif
g_queue_init(&wrk->keep_alive_queue);
ev_init(&wrk->keep_alive_timer, worker_keepalive_cb);
wrk->keep_alive_timer.data = wrk;
@ -508,6 +522,11 @@ void li_worker_free(liWorker *wrk) {
li_stat_cache_free(wrk->stat_cache);
#ifdef HAVE_LUA_H
lua_close(wrk->L);
wrk->L = NULL;
#endif
g_slice_free(liWorker, wrk);
}

Loading…
Cancel
Save