2
0
Fork 0

[lua] add per lua_State lock

This commit is contained in:
Stefan Bühler 2013-05-04 13:11:25 +02:00
parent c1851a6cea
commit 0d85a068c8
24 changed files with 185 additions and 157 deletions

View File

@ -24,12 +24,12 @@ local basepath = filename:gsub("(.*/)(.*)", "%1")
-- the basic CGI protocol)
--
-- Usage:
-- core.wsgi ( <url-prefix>, ${ <backend-actions>; } );
-- core.wsgi ( <url-prefix>, { <backend-actions>; } );
--
-- Example: Trac in "/trac", listening via FastCGI on unix:/tmp/trac.socket
-- You oviously have to load mod_fastcgi for this.
--
-- core.wsgi ( "/trac", ${ fastcgi "unix:/tmp/trac.socket"; } );
-- core.wsgi ( "/trac", { fastcgi "unix:/tmp/trac.socket"; } );
local function wsgi(uri_prefix, act)
if type(uri_prefix) ~= "string" then

View File

@ -39,6 +39,7 @@
#include <lighttpd/waitqueue.h>
#include <lighttpd/radix.h>
#include <lighttpd/base_lua.h>
#include <lighttpd/log.h>
#include <lighttpd/server.h>
#include <lighttpd/worker.h>

View File

@ -0,0 +1,20 @@
#ifndef _LIGHTTPD_BASE_LUA_H_
#define _LIGHTTPD_BASE_LUA_H_
#ifndef _LIGHTTPD_BASE_H_
#error Please include <lighttpd/base.h> instead of this file
#endif
/* this file defines lighttpd <-> lua glue which is always active, even if compiled without lua */
struct lua_State;
struct liLuaState {
struct lua_State* L; /** NULL if compiled without Lua */
GStaticRecMutex lualock;
};
LI_API void li_lua_init(liLuaState* LL, liServer* srv, liWorker* wrk);
LI_API void li_lua_clear(liLuaState* LL);
#endif

View File

@ -5,7 +5,7 @@
#include <lualib.h>
LI_API gboolean li_config_lua_load(lua_State *L, liServer *srv, liWorker *wrk, const gchar *filename, liAction **pact, gboolean allow_setup, liValue *args);
LI_API gboolean li_config_lua_load(liLuaState *LL, liServer *srv, liWorker *wrk, const gchar *filename, liAction **pact, gboolean allow_setup, liValue *args);
LI_API gboolean li_lua_config_publish_str_hash(liServer *srv, liWorker *wrk, lua_State *L, GHashTable *ht, int (*wrapper)(liServer *srv, liWorker *wrk, lua_State *L, gpointer data));
LI_API int li_lua_config_handle_server_action(liServer *srv, liWorker *wrk, lua_State *L, gpointer _sa);

View File

@ -4,8 +4,15 @@
#include <lighttpd/base.h>
#include <lua.h>
#define li_lua_lock(srv) g_static_rec_mutex_lock(&(srv)->lualock);
#define li_lua_unlock(srv) g_static_rec_mutex_unlock(&(srv)->lualock);
#define LI_LUA_REGISTRY_STATE "lighttpd.state"
#define LI_LUA_REGISTRY_SERVER "lighttpd.server"
#define LI_LUA_REGISTRY_WORKER "lighttpd.worker"
#define LI_LUA_REGISTRY_GLOBALS "lighttpd.globals"
LI_API liLuaState *li_lua_state_get(lua_State *L);
INLINE void li_lua_lock(liLuaState *LL);
INLINE void li_lua_unlock(liLuaState *LL);
LI_API void li_lua_init_chunk_mt(lua_State *L);
LI_API liChunk* li_lua_get_chunk(lua_State *L, int ndx);
@ -69,7 +76,7 @@ LI_API int li_lua_fixindex(lua_State *L, int ndx);
*/
LI_API int li_lua_metatable_index(lua_State *L);
LI_API void li_lua_init(lua_State* L, liServer* srv, liWorker* wrk);
LI_API void li_lua_init2(liLuaState* LL, liServer* srv, liWorker* wrk);
LI_API int li_lua_push_traceback(lua_State *L, int nargs);
@ -100,4 +107,18 @@ LI_API int li_lua_ghashtable_gstring_pairs(lua_State *L, GHashTable *ht);
/* internal: subrequests (vrequest metamethod) */
LI_API int li_lua_vrequest_subrequest(lua_State *L);
/* inline implementations */
INLINE void li_lua_lock(liLuaState *LL) {
gboolean b;
g_static_rec_mutex_lock(&LL->lualock);
b = lua_checkstack(LL->L, LUA_MINSTACK);
assert(b);
}
INLINE void li_lua_unlock(liLuaState *LL) {
g_static_rec_mutex_unlock(&LL->lualock);
}
#endif

View File

@ -24,8 +24,7 @@ typedef void (*liPluginHandleCloseCB) (liConnection *con, liPlugin *p);
typedef liHandlerResult(*liPluginHandleVRequestCB)(liVRequest *vr, liPlugin *p);
typedef void (*liPluginHandleVRCloseCB) (liVRequest *vr, liPlugin *p);
struct lua_State;
typedef void (*liPluginInitLua)(struct lua_State *L, liServer *srv, liWorker *wrk, liPlugin *p);
typedef void (*liPluginInitLua)(liLuaState *LL, liServer *srv, liWorker *wrk, liPlugin *p);
struct liPlugin {
@ -195,7 +194,7 @@ LI_API gboolean li_call_setup(liServer *srv, const char *name, liValue *val);
/** free val after call */
LI_API gboolean li_plugin_set_default_option(liServer *srv, const gchar* name, liValue *val);
LI_API void li_plugins_init_lua(struct lua_State *L, liServer *srv, liWorker *wrk);
LI_API void li_plugins_init_lua(liLuaState *LL, liServer *srv, liWorker *wrk);
extern liOptionPtrValue li_option_ptr_zero;

View File

@ -5,8 +5,6 @@
#error Please include <lighttpd/base.h> instead of this file
#endif
struct lua_State;
#ifndef LIGHTTPD_SERVER_MAGIC
# define LIGHTTPD_SERVER_MAGIC ((guint)0x12AB34CD)
#endif
@ -66,8 +64,7 @@ struct liServer {
liServerState state_wait_for;
ev_async state_ready_watcher;
GStaticRecMutex lualock;
struct lua_State *L; /** NULL if compiled without Lua */
liLuaState LL;
liWorker *main_worker;
guint worker_count;

View File

@ -46,6 +46,10 @@ typedef enum {
LI_BACKEND_DEAD
} liBackendError;
/* base_lua.h */
typedef struct liLuaState liLuaState;
/* chunk.h */
typedef struct liChunkFile liChunkFile;

View File

@ -64,7 +64,7 @@ struct liWorker {
GThread *thread; /* managed by server.c */
guint ndx; /* worker index */
struct lua_State *L; /** NULL if compiled without Lua */
liLuaState LL;
struct ev_loop *loop;
ev_prepare loop_prepare;

View File

@ -204,6 +204,7 @@ SET(LIGHTTPD_SHARED_SRC
angel.c
angel_fake.c
actions.c
base_lua.c
chunk.c
chunk_parser.c
collect.c

View File

@ -8,6 +8,7 @@ lighttpd_shared_src= \
angel.c \
angel_fake.c \
actions.c \
base_lua.c \
chunk.c \
chunk_parser.c \
collect.c \

View File

@ -22,11 +22,16 @@ liAction* li_lua_get_action(lua_State *L, int ndx) {
static int lua_action_gc(lua_State *L) {
liServer *srv;
liLuaState *LL = li_lua_state_get(L);
liAction **a = (liAction**) luaL_checkudata(L, 1, LUA_ACTION);
if (!a || !*a) return 0;
srv = (liServer*) lua_touserdata(L, lua_upvalueindex(1));
li_lua_unlock(LL);
li_action_release(srv, *a);
li_lua_lock(LL);
return 0;
}
@ -49,7 +54,7 @@ int li_lua_push_action(liServer *srv, lua_State *L, liAction *a) {
typedef struct lua_action_param lua_action_param;
struct lua_action_param {
int func_ref;
lua_State *L;
liLuaState *LL;
};
typedef struct lua_action_ctx lua_action_ctx;
@ -61,12 +66,11 @@ static liHandlerResult lua_action_func(liVRequest *vr, gpointer param, gpointer
lua_action_param *par = param;
lua_action_ctx *ctx = *context;
liServer *srv = vr->wrk->srv;
lua_State *L = par->L;
gboolean dolock = (L == srv->L);
lua_State *L = par->LL->L;
liHandlerResult res = LI_HANDLER_GO_ON;
int errfunc;
if (dolock) li_lua_lock(srv);
li_lua_lock(par->LL);
lua_rawgeti(L, LUA_REGISTRYINDEX, par->func_ref);
lua_pushvalue(L, -1);
@ -113,7 +117,7 @@ static liHandlerResult lua_action_func(liVRequest *vr, gpointer param, gpointer
lua_setfield(L, -2, "_G");
lua_pop(L, 2);
if (dolock) li_lua_unlock(srv);
li_lua_unlock(par->LL);
return res;
}
@ -121,13 +125,12 @@ static liHandlerResult lua_action_func(liVRequest *vr, gpointer param, gpointer
static liHandlerResult lua_action_cleanup(liVRequest *vr, gpointer param, gpointer context) {
lua_action_param *par = param;
lua_action_ctx *ctx = context;
liServer *srv = vr->wrk->srv;
lua_State *L = par->L;
gboolean dolock = (L == srv->L);
lua_State *L = par->LL->L;
UNUSED(vr);
if (dolock) li_lua_lock(srv);
li_lua_lock(par->LL);
luaL_unref(L, LUA_REGISTRYINDEX, ctx->g_ref);
if (dolock) li_lua_unlock(srv);
li_lua_unlock(par->LL);
g_slice_free(lua_action_ctx, ctx);
@ -137,16 +140,16 @@ static liHandlerResult lua_action_cleanup(liVRequest *vr, gpointer param, gpoint
static void lua_action_free(liServer *srv, gpointer param) {
lua_action_param *par = param;
lua_State *L;
gboolean dolock;
UNUSED(srv);
if (!param) return;
L = par->L;
dolock = (L == srv->L);
L = par->LL->L;
if (dolock) li_lua_lock(srv);
li_lua_lock(par->LL);
luaL_unref(L, LUA_REGISTRYINDEX, par->func_ref);
if (dolock) li_lua_unlock(srv);
lua_gc(L, LUA_GCCOLLECT, 0);
li_lua_unlock(par->LL);
g_slice_free(lua_action_param, par);
}
@ -155,20 +158,20 @@ liAction* li_lua_make_action(lua_State *L, int ndx) {
lua_action_param *par = g_slice_new0(lua_action_param);
liWorker *wrk;
lua_getfield(L, LUA_REGISTRYINDEX, "lighty.wrk");
lua_getfield(L, LUA_REGISTRYINDEX, LI_LUA_REGISTRY_WORKER);
wrk = lua_touserdata(L, -1);
lua_pop(L, 1);
lua_pushvalue(L, ndx); /* +1 */
par->func_ref = luaL_ref(L, LUA_REGISTRYINDEX); /* -1 */
par->L = L;
par->LL = li_lua_state_get(L);
/* new environment for function */
lua_pushvalue(L, ndx); /* +1 */
lua_newtable(L); /* +1 */
/* new mt */
lua_newtable(L); /* +1 */
lua_getfield(L, LUA_REGISTRYINDEX, "li_globals"); /* +1 */
lua_getfield(L, LUA_REGISTRYINDEX, LI_LUA_REGISTRY_GLOBALS); /* +1 */
lua_setfield(L, -2, "__index"); /* -1 */
lua_setmetatable(L, -2); /* -1 */
if (NULL != wrk) {

View File

@ -142,18 +142,18 @@ int li_lua_config_handle_server_action(liServer *srv, liWorker *wrk, lua_State *
liServerAction *sa = (liServerAction*) _sa;
liValue *val;
liAction *a;
gboolean dolock = (L == srv->L);
liLuaState *LL = li_lua_state_get(L);
lua_checkstack(L, 16);
val = lua_params_to_value(srv, L);
if (dolock) li_lua_unlock(srv);
li_lua_unlock(LL);
/* TRACE(srv, "%s", "Creating action"); */
a = sa->create_action(srv, wrk, sa->p, val, sa->userdata);
li_value_free(val);
if (dolock) li_lua_lock(srv);
li_lua_lock(LL);
if (NULL == a) {
lua_pushstring(L, "creating action failed");
@ -167,16 +167,16 @@ int li_lua_config_handle_server_setup(liServer *srv, liWorker *wrk, lua_State *L
liServerSetup *ss = (liServerSetup*) _ss;
liValue *val;
gboolean res;
gboolean dolock = (L == srv->L);
liLuaState *LL = li_lua_state_get(L);
UNUSED(wrk);
lua_checkstack(L, 16);
val = lua_params_to_value(srv, L);
if (dolock) li_lua_unlock(srv);
li_lua_unlock(LL);
/* TRACE(srv, "%s", "Calling setup"); */
res = ss->setup(srv, ss->p, val, ss->userdata);
if (dolock) li_lua_lock(srv);
li_lua_lock(LL);
if (!res) {
li_value_free(val);
@ -188,14 +188,14 @@ int li_lua_config_handle_server_setup(liServer *srv, liWorker *wrk, lua_State *L
return 0;
}
gboolean li_config_lua_load(lua_State *L, liServer *srv, liWorker *wrk, const gchar *filename, liAction **pact, gboolean allow_setup, liValue *args) {
gboolean li_config_lua_load(liLuaState *LL, liServer *srv, liWorker *wrk, const gchar *filename, liAction **pact, gboolean allow_setup, liValue *args) {
int errfunc;
int lua_stack_top;
gboolean dolock = (L == srv->L);
lua_State *L = LL->L;
*pact = NULL;
if (dolock) li_lua_lock(srv);
li_lua_lock(LL);
lua_stack_top = lua_gettop(L);
@ -235,7 +235,7 @@ gboolean li_config_lua_load(lua_State *L, liServer *srv, liWorker *wrk, const gc
li_lua_restore_globals(L);
if (dolock) li_lua_unlock(srv);
li_lua_unlock(LL);
return FALSE;
}
@ -251,7 +251,7 @@ gboolean li_config_lua_load(lua_State *L, liServer *srv, liWorker *wrk, const gc
lua_gc(L, LUA_GCCOLLECT, 0);
if (dolock) li_lua_unlock(srv);
li_lua_unlock(LL);
return TRUE;
}

View File

@ -623,7 +623,7 @@ static gboolean config_parser_include(liServer *srv, GList *ctx_stack, gchar *pa
return FALSE;
}
if (!li_config_lua_load(srv->L, srv, srv->main_worker, val->data.string->str, &a, TRUE, NULL)) {
if (!li_config_lua_load(&srv->LL, srv, srv->main_worker, val->data.string->str, &a, TRUE, NULL)) {
ERROR(srv, "include_lua '%s' failed", val->data.string->str);
li_value_free(val);
return FALSE;

View File

@ -4,6 +4,18 @@
#include <lualib.h>
#include <lauxlib.h>
liLuaState *li_lua_state_get(lua_State *L) {
liLuaState *LL;
lua_getfield(L, LUA_REGISTRYINDEX, LI_LUA_REGISTRY_STATE); /* +1 */
LL = lua_touserdata(L, -1);
lua_pop(L, 1);
assert(LL != NULL && LL->L == L);
return LL;
}
/* replace a negative stack index with a positive one,
* so that you don't need to care about push/pop
*/
@ -87,7 +99,7 @@ int li_lua_metatable_index(lua_State *L) {
static void li_lua_store_globals(lua_State *L) {
/* backup global table reference */
lua_pushvalue(L, LUA_GLOBALSINDEX); /* +1 */
lua_setfield(L, LUA_REGISTRYINDEX, "li_globals"); /* -1 */
lua_setfield(L, LUA_REGISTRYINDEX, LI_LUA_REGISTRY_GLOBALS); /* -1 */
}
GString* li_lua_print_get_string(lua_State *L, int from, int to) {
@ -245,7 +257,9 @@ static void lua_push_constants(lua_State *L, int ndx) {
lua_setfield(L, ndx, "HANDLER_ERROR");
}
void li_lua_init(lua_State *L, liServer *srv, liWorker *wrk) {
void li_lua_init2(liLuaState *LL, liServer *srv, liWorker *wrk) {
lua_State *L = LL->L;
li_lua_init_chunk_mt(L);
li_lua_init_coninfo_mt(L);
li_lua_init_environment_mt(L);
@ -259,10 +273,10 @@ void li_lua_init(lua_State *L, liServer *srv, liWorker *wrk) {
/* prefer closure, but just in case */
lua_pushlightuserdata(L, srv);
lua_setfield(L, LUA_REGISTRYINDEX, "lighty.srv");
lua_setfield(L, LUA_REGISTRYINDEX, LI_LUA_REGISTRY_SERVER);
if (NULL != wrk) {
lua_pushlightuserdata(L, wrk);
lua_setfield(L, LUA_REGISTRYINDEX, "lighty.wrk");
lua_setfield(L, LUA_REGISTRYINDEX, LI_LUA_REGISTRY_WORKER);
}
lua_newtable(L); /* lighty. */
@ -306,11 +320,11 @@ void li_lua_init(lua_State *L, liServer *srv, liWorker *wrk) {
li_lua_store_globals(L);
li_plugins_init_lua(L, srv, wrk);
li_plugins_init_lua(LL, srv, wrk);
}
void li_lua_restore_globals(lua_State *L) {
lua_getfield(L, LUA_REGISTRYINDEX, "li_globals"); /* +1 */
lua_getfield(L, LUA_REGISTRYINDEX, LI_LUA_REGISTRY_GLOBALS); /* +1 */
lua_replace(L, LUA_GLOBALSINDEX); /* -1 */
}

View File

@ -152,23 +152,22 @@ int li_lua_push_filter(lua_State *L, liFilter *f) {
typedef struct filter_lua_config filter_lua_config;
struct filter_lua_config {
lua_State *L;
liLuaState *LL;
int class_ref;
};
typedef struct filter_lua_state filter_lua_state;
struct filter_lua_state {
lua_State *L;
liLuaState *LL;
int object_ref;
};
static filter_lua_state* filter_lua_state_new(liVRequest *vr, filter_lua_config *config) {
int object_ref = LUA_NOREF;
liServer *srv = vr->wrk->srv;
lua_State *L = config->L;
gboolean dolock = (L == srv->L);
lua_State *L = config->LL->L;
if (dolock) li_lua_lock(srv);
li_lua_lock(config->LL);
lua_rawgeti(L, LUA_REGISTRYINDEX, config->class_ref); /* +1 */
li_lua_push_vrequest(L, vr); /* +1 */
@ -184,11 +183,11 @@ static filter_lua_state* filter_lua_state_new(liVRequest *vr, filter_lua_config
li_vrequest_error(vr);
}
if (dolock) li_lua_unlock(srv);
li_lua_unlock(config->LL);
if (LUA_NOREF != object_ref) {
filter_lua_state *state = g_slice_new0(filter_lua_state);
state->L = L;
state->LL = config->LL;
state->object_ref = object_ref;
return state;
@ -199,10 +198,9 @@ static filter_lua_state* filter_lua_state_new(liVRequest *vr, filter_lua_config
static void filter_lua_state_free(liVRequest *vr, filter_lua_state *state) {
liServer *srv = vr->wrk->srv;
lua_State *L = state->L;
gboolean dolock = (L == srv->L);
lua_State *L = state->LL->L;
if (dolock) li_lua_lock(srv);
li_lua_lock(state->LL);
lua_rawgeti(L, LUA_REGISTRYINDEX, state->object_ref); /* +1 */
li_lua_push_vrequest(L, vr); /* +1 */
@ -210,7 +208,7 @@ static void filter_lua_state_free(liVRequest *vr, filter_lua_state *state) {
luaL_unref(L, LUA_REGISTRYINDEX, state->object_ref);
if (dolock) li_lua_unlock(srv);
li_lua_unlock(state->LL);
g_slice_free(filter_lua_state, state);
}
@ -223,12 +221,10 @@ static void filter_lua_free(liVRequest *vr, liFilter *f) {
static liHandlerResult filter_lua_handle(liVRequest *vr, liFilter *f) {
filter_lua_state *state = (filter_lua_state*) f->param;
liServer *srv = vr->wrk->srv;
lua_State *L = state->L;
gboolean dolock = (L == srv->L);
lua_State *L = state->LL->L;
liHandlerResult res;
if (dolock) li_lua_lock(srv);
li_lua_lock(state->LL);
lua_rawgeti(L, LUA_REGISTRYINDEX, state->object_ref); /* +1 */
li_lua_push_vrequest(L, vr); /* +1 */
@ -255,7 +251,7 @@ static liHandlerResult filter_lua_handle(liVRequest *vr, liFilter *f) {
res = LI_HANDLER_ERROR;
}
if (dolock) li_lua_unlock(srv);
li_lua_unlock(state->LL);
return res;
}
@ -286,17 +282,18 @@ static liHandlerResult filter_lua_out(liVRequest *vr, gpointer param, gpointer *
static void filter_lua_action_free(liServer *srv, gpointer param) {
filter_lua_config *config = param;
lua_State *L = config->L;
gboolean dolock = (L == srv->L);
lua_State *L = config->LL->L;
UNUSED(srv);
if (dolock) li_lua_lock(srv);
li_lua_lock(config->LL);
luaL_unref(L, LUA_REGISTRYINDEX, config->class_ref);
if (dolock) li_lua_unlock(srv);
li_lua_unlock(config->LL);
g_slice_free(filter_lua_config, config);
}
static int filter_lua_action_create(lua_State *L, liActionFuncCB act_cb) {
liLuaState *LL = li_lua_state_get(L);
liServer *srv = lua_touserdata(L, lua_upvalueindex(1));
liAction *act;
filter_lua_config *config;
@ -310,7 +307,7 @@ static int filter_lua_action_create(lua_State *L, liActionFuncCB act_cb) {
}
config = g_slice_new0(filter_lua_config);
config->L = L;
config->LL = LL;
config->class_ref = luaL_ref(L, LUA_REGISTRYINDEX);
act = li_action_new_function(act_cb, NULL, filter_lua_action_free, config);
@ -337,11 +334,12 @@ void li_lua_init_filters(lua_State *L, liServer* srv) {
liFilter* li_lua_vrequest_add_filter_in(lua_State *L, liVRequest *vr, int state_ndx) {
filter_lua_state *state;
liLuaState *LL = li_lua_state_get(L);
lua_pushvalue(L, state_ndx);
state = g_slice_new0(filter_lua_state);
state->L = L;
state->LL = LL;
state->object_ref = luaL_ref(L, LUA_REGISTRYINDEX);
return li_vrequest_add_filter_in(vr, filter_lua_handle, filter_lua_free, state);
@ -349,11 +347,12 @@ liFilter* li_lua_vrequest_add_filter_in(lua_State *L, liVRequest *vr, int state_
liFilter* li_lua_vrequest_add_filter_out(lua_State *L, liVRequest *vr, int state_ndx) {
filter_lua_state *state;
liLuaState *LL = li_lua_state_get(L);
lua_pushvalue(L, state_ndx);
state = g_slice_new0(filter_lua_state);
state->L = L;
state->LL = LL;
state->object_ref = luaL_ref(L, LUA_REGISTRYINDEX);
return li_vrequest_add_filter_out(vr, filter_lua_handle, filter_lua_free, state);

View File

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

View File

@ -688,7 +688,7 @@ void li_plugins_stop_log(liServer *srv) { /* "suspend now" */
}
}
void li_plugins_init_lua(struct lua_State *L, liServer *srv, liWorker *wrk) {
void li_plugins_init_lua(liLuaState *LL, liServer *srv, liWorker *wrk) {
GHashTableIter iter;
liPlugin *p;
gpointer v;
@ -699,7 +699,7 @@ void li_plugins_init_lua(struct lua_State *L, liServer *srv, liWorker *wrk) {
while (g_hash_table_iter_next(&iter, NULL, &v)) {
p = (liPlugin*) v;
if (p->handle_init_lua) {
p->handle_init_lua(L, srv, wrk, p);
p->handle_init_lua(LL, srv, wrk, p);
}
}
}

View File

@ -2,12 +2,6 @@
#include <lighttpd/base.h>
#include <lighttpd/plugin_core.h>
#ifdef HAVE_LUA_H
# include <lighttpd/core_lua.h>
# include <lualib.h>
# include <lauxlib.h>
#endif
#ifdef HAVE_SYS_RESOURCE_H
# include <sys/resource.h>
#endif
@ -105,15 +99,7 @@ liServer* li_server_new(const gchar *module_dir, gboolean module_resident) {
ev_init(&srv->state_ready_watcher, state_ready_cb);
srv->state_ready_watcher.data = srv;
#ifdef HAVE_LUA_H
srv->L = luaL_newstate();
luaL_openlibs(srv->L);
li_lua_init(srv->L, srv, NULL);
g_static_rec_mutex_free(&srv->lualock);
#else
srv->L = NULL;
#endif
li_lua_init(&srv->LL, srv, NULL);
srv->workers = g_array_new(FALSE, TRUE, sizeof(liWorker*));
srv->worker_count = 0;
@ -213,11 +199,7 @@ void li_server_free(liServer* srv) {
li_ev_safe_ref_and_stop(ev_async_stop, srv->loop, &srv->state_ready_watcher);
g_mutex_free(srv->statelock);
#ifdef HAVE_LUA_H
lua_close(srv->L);
srv->L = NULL;
g_static_rec_mutex_free(&srv->lualock);
#endif
li_lua_clear(&srv->LL);
/* free throttle pools */
{
@ -363,10 +345,8 @@ static gboolean li_server_worker_init(liServer *srv) {
ev_timer_start(loop, &srv->srv_1sec_timer);
ev_unref(loop); /* don't keep loop alive */
#ifdef HAVE_LUA_H
li_plugins_init_lua(srv->L, srv, NULL);
li_plugins_init_lua(srv->main_worker->L, srv, srv->main_worker);
#endif
li_plugins_init_lua(&srv->LL, srv, NULL);
li_plugins_init_lua(&srv->main_worker->LL, srv, srv->main_worker);
if (srv->worker_count < 1) srv->worker_count = 1;
g_array_set_size(srv->workers, srv->worker_count);
@ -380,9 +360,7 @@ static gboolean li_server_worker_init(liServer *srv) {
wrk = g_array_index(srv->workers, liWorker*, i) = li_worker_new(srv, loop);
wrk->ndx = i;
#ifdef HAVE_LUA_H
li_plugins_init_lua(wrk->L, srv, wrk);
#endif
li_plugins_init_lua(&wrk->LL, srv, wrk);
}
return TRUE;

View File

@ -9,7 +9,7 @@ typedef struct liSubrequest liSubrequest;
struct liSubrequest {
liWorker *wrk;
lua_State *L;
liLuaState *LL;
int func_notify_ref, func_error_ref;
liVRequest *vr;
@ -197,13 +197,12 @@ static int li_lua_push_subrequest(lua_State *L, liSubrequest *sr) {
static void subvr_run_lua(liSubrequest *sr, int func_ref) {
liServer *srv = sr->wrk->srv;
lua_State *L = sr->L;
gboolean dolock = (L == srv->L);
lua_State *L = sr->LL->L;
int errfunc;
if (NULL == L || LUA_REFNIL == func_ref) return;
if (dolock) li_lua_lock(srv);
li_lua_lock(sr->LL);
lua_rawgeti(L, LUA_REGISTRYINDEX, func_ref);
@ -216,28 +215,29 @@ static void subvr_run_lua(liSubrequest *sr, int func_ref) {
}
lua_remove(L, errfunc);
if (dolock) li_lua_unlock(srv);
li_lua_unlock(sr->LL);
}
static void subvr_release_lua(liSubrequest *sr) {
liServer *srv = sr->wrk->srv;
lua_State *L = sr->L;
gboolean dolock = (L == srv->L);
lua_State *L;
liLuaState *LL = sr->LL;
if (NULL == L) return;
if (NULL == LL) return;
sr->L = NULL;
L = LL->L;
sr->LL = NULL;
if (dolock) li_lua_lock(srv);
li_lua_lock(LL);
luaL_unref(L, LUA_REGISTRYINDEX, sr->func_notify_ref);
luaL_unref(L, LUA_REGISTRYINDEX, sr->func_error_ref);
if (dolock) li_lua_unlock(srv);
li_lua_unlock(LL);
}
static void subvr_bind_lua(liSubrequest *sr, lua_State *L, int notify_ndx, int error_ndx) {
sr->L = L;
static void subvr_bind_lua(liSubrequest *sr, liLuaState *LL, int notify_ndx, int error_ndx) {
lua_State *L = LL->L;
sr->LL = LL;
lua_pushvalue(L, notify_ndx); /* +1 */
sr->func_notify_ref = luaL_ref(L, LUA_REGISTRYINDEX); /* -1 */
@ -341,13 +341,14 @@ static liSubrequest* subrequest_new(liVRequest *vr) {
static int lua_subrequest_gc(lua_State *L) {
liSubrequest *sr = li_lua_get_subrequest(L, 1);
liServer *srv = sr->wrk->srv;
gboolean dolock = (L == srv->L);
sr->L = NULL;
liLuaState *LL;
if (NULL == sr) return 0;
if (dolock) li_lua_unlock(srv); /* "pause" lua */
LL = sr->LL;
sr->LL = NULL;
li_lua_unlock(LL); /* "pause" lua */
if (sr->vr) {
li_vrequest_free(sr->vr);
@ -364,7 +365,7 @@ static int lua_subrequest_gc(lua_State *L) {
li_job_async(sr->parentvr_ref);
li_job_ref_release(sr->parentvr_ref);
if (dolock) li_lua_lock(srv);
li_lua_lock(LL);
return 0;
}
@ -383,7 +384,7 @@ int li_lua_vrequest_subrequest(lua_State *L) {
sr = subrequest_new(vr);
if (NULL == sr) return 0;
subvr_bind_lua(sr, L, 3, 4);
subvr_bind_lua(sr, li_lua_state_get(L), 3, 4);
li_action_enter(sr->vr, a);
li_vrequest_handle_request_headers(sr->vr);

View File

@ -3,12 +3,6 @@
#include <lighttpd/plugin_core.h>
#ifdef HAVE_LUA_H
# include <lighttpd/core_lua.h>
# include <lualib.h>
# include <lauxlib.h>
#endif
static liConnection* worker_con_get(liWorker *wrk);
/* closing sockets - wait for proper shutdown */
@ -346,13 +340,7 @@ 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
li_lua_init(&wrk->LL, srv, wrk);
g_queue_init(&wrk->keep_alive_queue);
ev_init(&wrk->keep_alive_timer, worker_keepalive_cb);
@ -487,10 +475,7 @@ void li_worker_free(liWorker *wrk) {
li_tasklet_pool_free(wrk->tasklets);
#ifdef HAVE_LUA_H
lua_close(wrk->L);
wrk->L = NULL;
#endif
li_lua_clear(&wrk->LL);
li_buffer_release(wrk->network_read_buf);

View File

@ -21,6 +21,7 @@ def build(bld):
actions.c
angel.c
angel_fake.c
base_lua.c
chunk.c
chunk_parser.c
collect.c

View File

@ -136,7 +136,7 @@ static liHandlerResult lua_handle(liVRequest *vr, gpointer param, gpointer *cont
li_action_release(vr->wrk->srv, wc->act);
wc->act = NULL;
if (!li_config_lua_load(vr->wrk->L, vr->wrk->srv, vr->wrk, conf->filename->str, &wc->act, FALSE, conf->args) || !wc->act) {
if (!li_config_lua_load(&vr->wrk->LL, vr->wrk->srv, vr->wrk, conf->filename->str, &wc->act, FALSE, conf->args) || !wc->act) {
VR_ERROR(vr, "lua.handler: couldn't load '%s'", conf->filename->str);
return LI_HANDLER_ERROR;
}
@ -291,14 +291,14 @@ static int push_args(lua_State *L, liValue *val) {
}
static gboolean lua_plugin_handle_setup(liServer *srv, liPlugin *p, liValue *val, gpointer userdata) {
lua_State *L = srv->L;
lua_State *L = srv->LL.L;
int lua_ref = GPOINTER_TO_INT(userdata);
int nargs, errfunc;
gboolean res;
UNUSED(p);
li_lua_lock(srv);
li_lua_lock(&srv->LL);
lua_rawgeti(L, LUA_REGISTRYINDEX, lua_ref);
nargs = push_args(L, val);
@ -319,20 +319,20 @@ static gboolean lua_plugin_handle_setup(liServer *srv, liPlugin *p, liValue *val
lua_remove(L, errfunc);
lua_gc(L, LUA_GCCOLLECT, 0);
li_lua_unlock(srv);
li_lua_unlock(&srv->LL);
return res;
}
static liAction* lua_plugin_handle_action(liServer *srv, liWorker *wrk, liPlugin* p, liValue *val, gpointer userdata) {
lua_State *L = srv->L;
lua_State *L = srv->LL.L;
int lua_ref = GPOINTER_TO_INT(userdata);
int nargs, errfunc;
liAction *res = NULL;
UNUSED(wrk); UNUSED(p);
li_lua_lock(srv);
li_lua_lock(&srv->LL);
lua_rawgeti(L, LUA_REGISTRYINDEX, lua_ref);
nargs = push_args(L, val);
@ -351,16 +351,16 @@ static liAction* lua_plugin_handle_action(liServer *srv, liWorker *wrk, liPlugin
lua_remove(L, errfunc);
lua_gc(L, LUA_GCCOLLECT, 0);
li_lua_unlock(srv);
li_lua_unlock(&srv->LL);
return res;
}
static void lua_plugin_free_data(liServer *srv, luaPlugin *lp) {
lua_State *L = srv->L;
lua_State *L = srv->LL.L;
guint i;
if (L) li_lua_lock(srv);
if (L) li_lua_lock(&srv->LL);
for (i = 0; i < lp->actions->len; i++) {
liPluginAction *pa = &g_array_index(lp->actions, liPluginAction, i);
@ -377,7 +377,7 @@ static void lua_plugin_free_data(liServer *srv, luaPlugin *lp) {
}
g_array_free(lp->setups, TRUE);
if (L) li_lua_unlock(srv);
if (L) li_lua_unlock(&srv->LL);
if (lp->filename)
g_string_free(lp->filename, TRUE);
@ -472,12 +472,12 @@ static void lua_plugin_init(liServer *srv, liPlugin *p, gpointer userdata) {
static gboolean lua_plugin_load(liServer *srv, liPlugin *p, GString *filename, liValue* args) {
int errfunc;
int lua_stack_top;
lua_State *L = srv->L;
lua_State *L = srv->LL.L;
luaPlugin *lp;
module_config *mc = p->data;
liPlugin *newp;
li_lua_lock(srv);
li_lua_lock(&srv->LL);
lua_stack_top = lua_gettop(L);
@ -527,7 +527,7 @@ static gboolean lua_plugin_load(liServer *srv, liPlugin *p, GString *filename, l
li_lua_restore_globals(L);
lua_gc(L, LUA_GCCOLLECT, 0);
li_lua_unlock(srv);
li_lua_unlock(&srv->LL);
lp->filename = filename;
@ -537,7 +537,7 @@ failed_unlock_lua:
lua_pop(L, lua_gettop(L) - lua_stack_top);
li_lua_restore_globals(L);
lua_gc(L, LUA_GCCOLLECT, 0);
li_lua_unlock(srv);
li_lua_unlock(&srv->LL);
g_string_free(filename, TRUE);

View File

@ -681,7 +681,7 @@ static void lua_memcache_callback(liMemcachedRequest *request, liMemcachedResult
liServer *srv;
int errfunc;
lua_getfield(L, LUA_REGISTRYINDEX, "lighty.srv");
lua_getfield(L, LUA_REGISTRYINDEX, LI_LUA_REGISTRY_SERVER);
srv = lua_touserdata(L, -1);
lua_pop(L, 1);
@ -1089,11 +1089,13 @@ static int mc_lua_new(lua_State *L) {
return li_lua_push_memcached_con(L, con);
}
static void mod_memcached_lua_init(lua_State *L, liServer *srv, liWorker *wrk, liPlugin *p) {
static void mod_memcached_lua_init(liLuaState *LL, liServer *srv, liWorker *wrk, liPlugin *p) {
lua_State *L = LL->L;
UNUSED(srv);
UNUSED(p);
if (wrk) {
li_lua_lock(LL);
lua_newtable(L); /* { } */
lua_pushlightuserdata(L, wrk);
@ -1101,6 +1103,7 @@ static void mod_memcached_lua_init(lua_State *L, liServer *srv, liWorker *wrk, l
lua_setfield(L, -2, "new");
lua_setfield(L, LUA_GLOBALSINDEX, "memcached");
li_lua_unlock(LL);
}
}
#endif