lua-users home
lua-l archive

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


On Mon, Mar 10, 2014 at 01:39:09PM -0500, Andrew Starks wrote:
<snip>
> I'm a huge fan of:
> 
> https://github.com/moteus/lua-llthreads2
> 
> ...which uses the same approach. The "fan" part comes from the totally
> comprehensible error messages that I get in the remote thread. They're
> like... normal.

The way my threading package reports errors is that thread:join() will
return the error. So there's no mucking with stderr or C functions.

Because there are no process blocking operations in my module (everything is
non-blocking), to wait for and catch errors in the new thread you can just
do:

	local thr, com1 = thread.start(function (com2, ...)
		-- com2 is one end of a socketpair shared with caller. we
		-- can pass file descriptors and other stuff back and forth.
	end)

	-- wait for and join our thread asychronously
	loop:wrap(function()
		local joined, why = thr:join()

		if not joined then
			cluck(why) --> system error when attempting to join
		elseif why then
			cluck(why) --> error from worker thread
		end
	end)


I noticed that llthreads doesn't initialize the signal mask in the new
thread. If you don't do this in a critical section at thread startup, then
you might run into potential signal race or routing issues unless the
application explicitly blocks signals before thread.start and restores
afterward. The canonical technique is to do

	sigfillset(&mask);
        sigemptyset(&omask);

        if ((error = pthread_sigmask(SIG_SETMASK, &mask, &omask)))
                goto error;

	/* create thread here, which inherits our signal mask */

	pthread_sigmask(SIG_SETMASK, &omask, NULL);


Also, much to my surprise, upstream OpenSSL _still_ doesn't automatically
initialize locking. I added OpenSSL mutex initialization to both my thread
module (which is part of a larger package which links with OpenSSL) as well
as my OpenSSL module (luaossl), in case it's used with other threading
modules.

The OpenSSL initialization code uses dladdr + dlopen to pin the code into
memory, making sure that OpenSSL locking callbacks don't disappear if the
Lua VM unloads the module. This technique could be used in lua-llthread2 to
make sure the set_logger handler doesn't become invalid.


Threading is hard. There's no room for shortcuts ;)