degesch: Lua coroutine safety
This commit is contained in:
parent
572f4e2ea3
commit
0247c4667a
99
degesch.c
99
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
|
||||
|
Loading…
Reference in New Issue
Block a user