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