lua-users home
lua-l archive

Re: Is the registry needed?

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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

AltStyle によって変換されたページ (->オリジナル) /