lua-users home
lua-l archive

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


On Mon, 2006-08-28 at 16:51 -0400, Michael Surette wrote:
> On Tuesday 22 August 2006 15:48, Wim Couwenberg wrote:
> >
> > And one more thing: anyone with some suggestions for round table subjects?
> >
> > --
> > Wim
> 
> I've been following the thread "Mulitiple functions" with interest because of 
> my similar problem.  I have lua functions defining C callbacks which need to 
> be reentrant.  My C application calls each lua callback in a separate lua 
> thread which needs access to globals as defined in the original script file.  
> It works well, with the unfortunate side effect is that all callback function 
> variables must be declared local to avoid cross-contamination between 
> threads.  
> 
> I believe that a low-overhead native-to-lua way of "cloning" functions between 
> threads, giving each an environment of your choice would be an ideal solution 
> to this problem and a good topic for the round table.

Not sure if you have additional restrictions, but I am doing exactly
this in an event-based SMTP server. It's all non-blocking I/O for
end-to-end, no threads except for heavily CPU bound tasks, so I really
didn't want Lua spending too much time doing useless work. Granted, I
was one of the people who brought up this topic last week because it was
less than straightforward and still requires some constraints in
practice.

When the daemon starts up it creates a global lua_State and loads the
Lua "firmware". Every SMTP connection creates a thread and installs an
environment which links back the global environment via an __index
metamethod. Also, a handful of context specific objects are instantiated
at some point (E for event, C for client, M for MIME). Every SMTP event
can be sent to a Lua function for processing. E.g.

function onConnect(ptrname, inetaddr)
	client_inetaddr = inetaddr

	-- rbl.lookup will yield Lua during the DNS query
	-- and renter the daemon I/O event loop
	if (rbl.lookup('spamcop.net', inetaddr) == '127.0.0.1') then
		E:apply({
			['action'] = 'reject',
			['text']   = '450 rejected by spamcop',
		})
	end
end

function onEnvFrom(sender, ...)
	if client_inetaddr ~= C:inetaddr() then
		M:addheader('X-Lua: i am a liar and will be fired')
	else
		log.warn('we should actually be here')
		log.warn('even if rbl.lookup yielded and')
		log.warn('other onConnect events executed')
	end
end


-- 
William Ahern <wahern@barracudanetworks.com>


--------------------------------------------------
This message was scanned for Spam, Spyware and Viruses
For more information, please visit:
http://www.barracudanetworks.com