From 0247c4667a8c63c8f657f4c782fdd4a591c1e1d0 Mon Sep 17 00:00:00 2001 From: Přemysl Janouch Date: Fri, 4 Nov 2016 18:51:32 +0100 Subject: degesch: Lua coroutine safety --- degesch.c | 99 +++++++++++++++++++++++++++++---------------------------------- 1 file changed, 46 insertions(+), 53 deletions(-) diff --git a/degesch.c b/degesch.c index d85c814..1718402 100644 --- a/degesch.c +++ b/degesch.c @@ -8385,7 +8385,7 @@ static bool lua_plugin_call (struct lua_plugin *self, int n_params, int n_results, struct error **e) { - // FIXME: this may be called from a thread, then this is wrong + // XXX: this may eventually be called from a thread, then this is wrong lua_State *L = self->L; // We need to pop the error handler at the end @@ -8844,11 +8844,9 @@ lua_weak_invalidate (void *object, void *user_data) } static void -lua_weak_push (struct lua_plugin *plugin, void *object, +lua_weak_push (lua_State *L, struct lua_plugin *plugin, void *object, struct lua_weak_info *info) { - // FIXME: this may be called from a thread, then this is wrong - lua_State *L = plugin->L; if (!object) { lua_pushnil (L); @@ -8937,7 +8935,7 @@ lua_user_get_channels (lua_State *L) lua_newtable (L); LIST_FOR_EACH (struct user_channel, iter, user->channels) { - lua_weak_push (wrapper->plugin, iter->channel, &lua_channel_info); + lua_weak_push (L, wrapper->plugin, iter->channel, &lua_channel_info); lua_rawseti (L, -2, i++); } return 1; @@ -8969,7 +8967,7 @@ lua_channel_get_users (lua_State *L) LIST_FOR_EACH (struct channel_user, iter, channel->users) { lua_createtable (L, 0, 2); - lua_weak_push (wrapper->plugin, iter->user, &lua_user_info); + lua_weak_push (L, wrapper->plugin, iter->user, &lua_user_info); lua_setfield (L, -2, "user"); lua_plugin_kv (L, "prefixes", iter->prefixes.str); @@ -9153,9 +9151,9 @@ lua_input_hook_filter (struct input_hook *self, struct buffer *buffer, lua_State *L = plugin->L; lua_rawgeti (L, LUA_REGISTRYINDEX, hook->ref_callback); - lua_rawgetp (L, LUA_REGISTRYINDEX, hook); // 1: hook - lua_weak_push (plugin, buffer, &lua_buffer_info); // 2: buffer - lua_pushstring (L, input); // 3: input + lua_rawgetp (L, LUA_REGISTRYINDEX, hook); // 1: hook + lua_weak_push (L, plugin, buffer, &lua_buffer_info); // 2: buffer + lua_pushstring (L, input); // 3: input struct error *e = NULL; if (lua_plugin_call (plugin, 3, 1, &e)) @@ -9177,9 +9175,9 @@ lua_irc_hook_filter (struct irc_hook *self, struct server *s, char *message) lua_State *L = plugin->L; lua_rawgeti (L, LUA_REGISTRYINDEX, hook->ref_callback); - lua_rawgetp (L, LUA_REGISTRYINDEX, hook); // 1: hook - lua_weak_push (plugin, s, &lua_server_info); // 2: server - lua_pushstring (L, message); // 3: message + lua_rawgetp (L, LUA_REGISTRYINDEX, hook); // 1: hook + lua_weak_push (L, plugin, s, &lua_server_info); // 2: server + lua_pushstring (L, message); // 3: message struct error *e = NULL; if (lua_plugin_call (plugin, 3, 1, &e)) @@ -9287,7 +9285,7 @@ lua_completion_hook_complete (struct completion_hook *self, lua_rawgetp (L, LUA_REGISTRYINDEX, hook); // 1: hook lua_plugin_push_completion (L, data); // 2: data - lua_weak_push (plugin, plugin->ctx->current_buffer, &lua_buffer_info); + lua_weak_push (L, plugin, plugin->ctx->current_buffer, &lua_buffer_info); lua_setfield (L, -2, "buffer"); lua_pushstring (L, word); // 3: word @@ -9325,11 +9323,9 @@ lua_timer_hook_dispatch (void *user_data) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - static struct lua_hook * -lua_plugin_push_hook (struct lua_plugin *plugin, int callback_index, - enum lua_hook_type type, int priority) +lua_plugin_push_hook (lua_State *L, struct lua_plugin *plugin, + int callback_index, enum lua_hook_type type, int priority) { - // FIXME: this may be called from a thread, then this is wrong - lua_State *L = plugin->L; luaL_checktype (L, callback_index, LUA_TFUNCTION); struct lua_hook *hook = lua_newuserdata (L, sizeof *hook); @@ -9352,7 +9348,7 @@ lua_plugin_hook_input (lua_State *L) { struct lua_plugin *plugin = lua_touserdata (L, lua_upvalueindex (1)); struct lua_hook *hook = lua_plugin_push_hook - (plugin, 1, XLUA_HOOK_INPUT, luaL_optinteger (L, 2, 0)); + (L, plugin, 1, XLUA_HOOK_INPUT, luaL_optinteger (L, 2, 0)); hook->data.input_hook.filter = lua_input_hook_filter; plugin->ctx->input_hooks = hook_insert (plugin->ctx->input_hooks, &hook->data.hook); @@ -9364,7 +9360,7 @@ lua_plugin_hook_irc (lua_State *L) { struct lua_plugin *plugin = lua_touserdata (L, lua_upvalueindex (1)); struct lua_hook *hook = lua_plugin_push_hook - (plugin, 1, XLUA_HOOK_IRC, luaL_optinteger (L, 2, 0)); + (L, plugin, 1, XLUA_HOOK_IRC, luaL_optinteger (L, 2, 0)); hook->data.irc_hook.filter = lua_irc_hook_filter; plugin->ctx->irc_hooks = hook_insert (plugin->ctx->irc_hooks, &hook->data.hook); @@ -9376,7 +9372,7 @@ lua_plugin_hook_prompt (lua_State *L) { struct lua_plugin *plugin = lua_touserdata (L, lua_upvalueindex (1)); struct lua_hook *hook = lua_plugin_push_hook - (plugin, 1, XLUA_HOOK_PROMPT, luaL_optinteger (L, 2, 0)); + (L, plugin, 1, XLUA_HOOK_PROMPT, luaL_optinteger (L, 2, 0)); hook->data.prompt_hook.make = lua_prompt_hook_make; plugin->ctx->prompt_hooks = hook_insert (plugin->ctx->prompt_hooks, &hook->data.hook); @@ -9389,7 +9385,7 @@ lua_plugin_hook_completion (lua_State *L) { struct lua_plugin *plugin = lua_touserdata (L, lua_upvalueindex (1)); struct lua_hook *hook = lua_plugin_push_hook - (plugin, 1, XLUA_HOOK_COMPLETION, luaL_optinteger (L, 2, 0)); + (L, plugin, 1, XLUA_HOOK_COMPLETION, luaL_optinteger (L, 2, 0)); hook->data.c_hook.complete = lua_completion_hook_complete; plugin->ctx->completion_hooks = hook_insert (plugin->ctx->completion_hooks, &hook->data.hook); @@ -9407,7 +9403,7 @@ lua_plugin_hook_timer (lua_State *L) // This doesn't really hook anything but we can reuse the code struct lua_hook *hook = lua_plugin_push_hook - (plugin, 1, XLUA_HOOK_TIMER, 0 /* priority doesn't apply */); + (L, plugin, 1, XLUA_HOOK_TIMER, 0 /* priority doesn't apply */); struct poller_timer *timer = &hook->data.timer; poller_timer_init (timer, &plugin->ctx->poller); @@ -9572,13 +9568,10 @@ lua_plugin_check_field (lua_State *L, int idx, const char *name, } static int -lua_plugin_add_config_schema (struct lua_plugin *plugin, +lua_plugin_add_config_schema (lua_State *L, struct lua_plugin *plugin, struct config_item *subtree, const char *name) { struct config_item *item = str_map_find (&subtree->value.object, name); - // FIXME: this may be called from a thread, then this is wrong - lua_State *L = plugin->L; - // This should only ever happen because of a conflict with another plugin; // this is the price we pay for simplicity if (item && item->schema) @@ -9682,7 +9675,7 @@ lua_plugin_setup_config (lua_State *L) return luaL_error (L, "%s: %s -> %s", "invalid types", lua_typename (L, lua_type (L, -2)), lua_typename (L, lua_type (L, -1))); - lua_plugin_add_config_schema (plugin, subtree, lua_tostring (L, -2)); + lua_plugin_add_config_schema (L, plugin, subtree, lua_tostring (L, -2)); } // Let the plugin read out configuration via on_change callbacks @@ -10140,17 +10133,17 @@ lua_plugin_panic (lua_State *L) } static void -lua_plugin_push_ref (struct lua_plugin *self, void *object, +lua_plugin_push_ref (lua_State *L, struct lua_plugin *self, void *object, struct ispect_field *field) { // We create a mapping on object type registration - hard_assert (lua_rawgetp (self->L, LUA_REGISTRYINDEX, field->fields)); - struct lua_weak_info *info = lua_touserdata (self->L, -1); - lua_pop (self->L, 1); + hard_assert (lua_rawgetp (L, LUA_REGISTRYINDEX, field->fields)); + struct lua_weak_info *info = lua_touserdata (L, -1); + lua_pop (L, 1); if (!field->is_list) { - lua_weak_push (self, object, info); + lua_weak_push (L, self, object, info); return; } @@ -10158,25 +10151,25 @@ lua_plugin_push_ref (struct lua_plugin *self, void *object, struct list_header { LIST_HEADER (void) }; int i = 1; - lua_newtable (self->L); + lua_newtable (L); LIST_FOR_EACH (struct list_header, iter, object) { - lua_weak_push (self, iter, info); - lua_rawseti (self->L, -2, i++); + lua_weak_push (L, self, iter, info); + lua_rawseti (L, -2, i++); } } -static void lua_plugin_push_map_field (struct lua_plugin *self, +static void lua_plugin_push_map_field (lua_State *L, struct lua_plugin *self, const char *key, void *p, struct ispect_field *field); static void -lua_plugin_push_struct (struct lua_plugin *self, enum ispect_type type, - void *value, struct ispect_field *field) +lua_plugin_push_struct (lua_State *L, struct lua_plugin *self, + enum ispect_type type, void *value, struct ispect_field *field) { if (type == ISPECT_STR) { struct str *s = value; - lua_pushlstring (self->L, s->str, s->len); + lua_pushlstring (L, s->str, s->len); return; } if (type == ISPECT_STR_MAP) @@ -10185,16 +10178,16 @@ lua_plugin_push_struct (struct lua_plugin *self, enum ispect_type type, str_map_iter_init (&iter, value); void *value; - lua_newtable (self->L); + lua_newtable (L); while ((value = str_map_iter_next (&iter))) - lua_plugin_push_map_field (self, iter.link->key, value, field); + lua_plugin_push_map_field (L, self, iter.link->key, value, field); return; } hard_assert (!"unhandled introspection object type"); } static void -lua_plugin_push_map_field (struct lua_plugin *self, +lua_plugin_push_map_field (lua_State *L, struct lua_plugin *self, const char *key, void *p, struct ispect_field *field) { // That would mean maps in maps ad infinitum @@ -10204,15 +10197,15 @@ lua_plugin_push_map_field (struct lua_plugin *self, switch (field->subtype) { // Here the types are generally casted to a void pointer - case ISPECT_BOOL: lua_pushboolean (self->L, (bool ) n); break; - case ISPECT_INT: lua_pushinteger (self->L, (int ) n); break; - case ISPECT_UINT: lua_pushinteger (self->L, (unsigned ) n); break; - case ISPECT_SIZE: lua_pushinteger (self->L, (size_t ) n); break; - case ISPECT_STRING: lua_pushstring (self->L, p); break; - case ISPECT_REF: lua_plugin_push_ref (self, p, field); break; - default: lua_plugin_push_struct (self, field->subtype, p, field); + case ISPECT_BOOL: lua_pushboolean (L, (bool ) n); break; + case ISPECT_INT: lua_pushinteger (L, (int ) n); break; + case ISPECT_UINT: lua_pushinteger (L, (unsigned ) n); break; + case ISPECT_SIZE: lua_pushinteger (L, (size_t ) n); break; + case ISPECT_STRING: lua_pushstring (L, p); break; + case ISPECT_REF: lua_plugin_push_ref (L, self, p, field); break; + default: lua_plugin_push_struct (L, self, field->subtype, p, field); } - lua_setfield (self->L, -2, key); + lua_setfield (L, -2, key); } static bool @@ -10241,8 +10234,8 @@ lua_plugin_property_get_ispect (lua_State *L, const char *property_name) case ISPECT_UINT: lua_pushinteger (L, *(unsigned *) p); break; case ISPECT_SIZE: lua_pushinteger (L, *(size_t *) p); break; case ISPECT_STRING: lua_pushstring (L, *(char **) p); break; - case ISPECT_REF: lua_plugin_push_ref (self, *(void **) p, field); break; - default: lua_plugin_push_struct (self, field->type, p, field); + case ISPECT_REF: lua_plugin_push_ref (L, self, *(void **) p, field); break; + default: lua_plugin_push_struct (L, self, field->type, p, field); } return true; } @@ -10376,7 +10369,7 @@ lua_plugin_load (struct app_context *ctx, const char *filename, lua_setfield (L, -2, "async"); lua_pop (L, 1); - lua_weak_push (plugin, ctx, &lua_ctx_info); + lua_weak_push (L, plugin, ctx, &lua_ctx_info); lua_setglobal (L, lua_ctx_info.name); // Create metatables for our objects -- cgit v1.2.3-70-g09d2