[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: interrupting coroutines (was Re: Local Variables)
- From: Sean Conner <sean@...>
- Date: Mon, 11 Aug 2014 21:55:40 -0400
It was thus said that the Great William Ahern once stated:
> On Mon, Aug 11, 2014 at 09:08:28PM -0400, Sean Conner wrote:
> <snip>
> > Not directly, but you can still gain control via a signal handler. Some
> > basic code:
> <snip>
> > volatile int ghookcount;
> > volatile int ghookmask;
> > volatile lua_Hook ghook;
> > volatile_sig_atomic_t gsig;
> <snip>
> > void signal_handler(int sig)
> > {
> > if (!gsig)
> > {
> > gsig = sig;
> > ghookcount = lua_gethookcount(gL);
> > ghookmask = lua_gethookmask(gL);
> > ghook = lua_gethook(gL);
> > lua_sethook(gL,luasigbackend,LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT,1);
> > }
> > }
>
> This can't be async-signal-safe unless all other signals are blocked during
> execution of the handler. So there should be the caveat that when installing
> the signal handler, sigfillset is used to initialize sa_mask.
This is the best you can do with ANSI-C signal semantics if you want to
gain control with a signal handler.
And yes, the way I do this under POSIX is technically a race condition
(two signals at the same time).
The previous version of signal handling I did, the code looked like:
volatile sig_atomic_t gsig;
volatile sig_atomic_t gsigs[NSIG];
void signal_handler(int sig)
{
gsig = 1;
gsigs[sig] = 1;
}
and it was up to the rest of the code to check gsig and the appropriate
gsigs[] entry. If you want portable and safe, that's it.
> > Yeah, it's a bit of a round-about way of doing things, but it appears to
> > tbe the safest way of handling signals in Lua. I've done two
> > implementations based on this method, on for ANSI-C only:
>
> The safest way is to not handle signals asynchronously at all.
"The safest way is to not handle signals ------------- at all."
Fixed that for you 8-P
> But the problem with sigtimedwait is that you often want some sort of
> concurrent execution of signal handlers without having to explicitly query
> them. My cqueues library provides an API for kernel-based, event-oriented
> signal management. Internally it uses signalfd on Linux and kqueue
> EVFILT_SIGNAL on BSDs (including OS X).
I must be running a Linux kernel older than 20 minutes because I don't
have signalfd on my system. [1]
> On systems like Solaris it queries
> sigtimedwait on a timer. The following example will work on all those
> systems:
>
> local signal = require"cqueues.signal"
> local sigfd = signal.listen(signal.SIGTERM, signal.SIGINT)
>
> while true do
> local signo = sigfd:wait() -- doesn't block process
>
> print(signo)
> end
But this won't handle the original problem:
coroutine.resume(coroutine.create(function() while true do end end))
-spc (thinks signals was one of the poorer thought out concepts of Unix)
[1] Not everybody updates their systems every ten minutes. I don't do
that, because I operate under the "if it ain't broke, don't fix it"
mandate. And because of that, I wasn't affected by Heartbleed. Nor
have I been bitten by updates borking my system.