[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Is the registry needed?
- From: Sean Conner <sean@...>
- Date: Wed, 30 Sep 2015 16:05:34 -0400
It was thus said that the Great Soni L. once stated:
>
> The same way you'd do it in Lua: Your module table. Or the metatable.
I went through my existing modules to see if I could forgo the use of the
registry table. So maybe you can help me. One problematic module:
local signal = require "org.conman.signal" -- [1]
signal.catch('interrupt',function()
print "You can't interrupt me! Muahahahaha!"
end)
Seems simple to use, but we need to save a reference to the passed in
function because, as in this example, it can be an anonymous function not
otherwise anchored into memory. Second, there are some 30+ signals we can
capture (keep that in mind). Third, our signal handler:
static void signal_handler(int sig)
{
...
Okay. No context other than the signal that was just generated. This
means we need to cache the lua_State in a variable visible to our signal
handler. That can be done during the luaopen() call, so now we have:
static lua_State *m_L;
static void signal_handler(int sig)
{
...
We're running in a signal handler. There is not much you can do *safely*
from a signal handler (because you could be in the middle of allocating
memory, in the middle of a Lua call, halfway through manipulating a linked
list, any number of half-finished states exist), and the *only* thing you
can safely call in Lua is lua_sethook(). Even trying to write the signal
number to a table is unsafe. So we have:
static lua_State *m_L;
static volatile sig_atomic_t m_sig;
static void signal_handler(int sig)
{
m_sig = sig;
lua_sethook(m_L,hook_handler,LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT,1);
}
We now resume from the signal, and when it's safe for Lua to do so, our
hook_handler() gets called:
static void hook_handler(lua_State *L,lua_Debug *ar)
{
...
}
Okay, where's our function to handle the signal? What meta table?
Where's the module table? I could try looking for
"package.loaded['org.conman.syslog']" but I can't rely upon that if the
global environment has been sandboxed (the global environment might have
'signal' already loaded, but not 'package' or 'require'). I don't want to
pollute the global environment. But I have no context to save or retrieve
which function to run.
Do you have any alternatives that don't rely upon package.loaded[]?
Because I have no ideas ...
-spc
[1] https://github.com/spc476/lua-conmanorg/blob/master/src/signal.c
- References:
- Re: Is the registry needed?, Dirk Laurie
- Re: Is the registry needed?, Soni L.
- Re: Is the registry needed?, Sean Conner
- Re: Is the registry needed?, Soni L.
- Re: Is the registry needed?, Luiz Henrique de Figueiredo
- Re: Is the registry needed?, Soni L.
- Re: Is the registry needed?, Sean Conner
- Re: Is the registry needed?, Soni L.
- Re: Is the registry needed?, Tim Hill
- Re: Is the registry needed?, Soni L.