[RFC] Toward Shareable POSIX Signals
Daniel Colascione
dancol@dancol.org
Fri Mar 9 10:51:00 GMT 2018
On 03/09/2018 12:17 AM, OndÅej BÃlka wrote:
> On Thu, Mar 08, 2018 at 01:50:17PM -0800, dancol@dancol.org wrote:
>>> On Thu, Mar 08, 2018 at 12:22:05PM -0800, dancol@dancol.org wrote:
>>>>> For asynchronously delivered signals (such as subprocess termination),
>>>>> the signal mechanism may not be entirely appropriate anyway.
>>>>
>>>> It beats wait. Which part of my proposed mechanism would operate
>>>> improperly?
>>>>
>>> Basic problem is that if you combine signals, threads and locks you get
>>> a big mess.
>>>
>>> It is hard to write handler doing something complex, you
>>> couldn't take any lock because thread you interrupted could have that
>>> lock. Introducing signal leads to unexpected race conditions(for example
>>> what happens when interrupt is interrupted?).
>>
>> Writing a robust handler requires some understanding of the subtleties
>> involved, but it's in no way impossible or even particularly difficult.
>> It's the moral equivalent of writing the top half of an interrupt handler.
>> People do that all the time.
>>
>> Besides: people are _already_ using signals for this purpose. Practically
>> every high-performance language runtime already hooks various signal
>> handlers, and for good reason. There's no reason it should be hard for
>> these systems to coexist in the same process, and something like glib does
>> nothing to help sharing.
>>
>> I'm proposing making existing use cases more portable and more robust.
>>
> Reality is that people don't bother and use first code that appears to
> work.
If you follow that line of thought to its logical conclusion, you end up
with banning C. Low-level libraries help let developers express their
design, not hold their hand because some techniques are thought to be
too dangerous in solutions pasted from Stack Overflow.
In any case, blocking an API like this won't stop people using signals.
It'll just make the signal hacking they do more dangerous.
>>>>> For those,
>>>>> standardizing on a single event loop looks like the right solution,
>>>> and
>>>>> glib has largely taken over there.
>>>>
>>>> The libevent and Qt people might disagree. I don't think standardizing
>>>> on
>>>> a single event loop is realistic considering that various event loop
>>>> libraries have been around for many years and not achieved any kind of
>>>> fixation.
>>>>
>>>
>>> Original answer to use event loop, doesn't matter which one.
>>
>> Nobody will agree on a single event loop library. There is, for example,
>> _zero_ chance that popular mobile operating systems will adopt glib as the
>> primary event dispatching mechanism. In any case, an event loop doesn't
>> help with the synchronous signal sharing use cases --- the ones, for
>> example, a SIGSEGV-using high-performance runtime might require. (See the
>> first of my use cases on my original post.)
>>
> Florian and I were talking about async signals and that they should be
> handled in single event loop to serialize them. That there may be other
> event loops is irrelevant.
If there are multiple event loop libraries, they need to arbitrate
access to signals somehow.
>>> Async signals should be handled as separate thread which has event loop
>>> to serially handle arrived signals. That would remove most difficulties
>>> of signal handlers.
>>>
>>> Reason why this isn't default is performance and putting this to another
>>> event loop is compromise.
>>
>>
>> It's not performance. It's that certain events, particularly those related
>> to memory errors, _need_ to be addressed immediately and synchronously.
>> Even if you were to use something like the Mach ports mechanism and send a
>> message instead of pushing a stack frame, you'd still have to
>> synchronously block a faulting thread, which could be anywhere, thus
>> giving you the same atomicity constraints.
>>
> This starts with
>
>>> Async signals
>
> So sync part isn't relevant.
Sure it is. With one API, you can cover both kinds of signal.
> Beside that you could do sync signals using
> different thread if you don't care about overhead. Kernel could create
> lock for offending thread/process, signal handler would run in different thread
> which would unlock to resume offending thread when condition was handled.
It doesn't help. A thread causing a synchronous signal can hold
arbitrary locks while blocked waiting for some other thread to service
that signal, so that handler code would still need to be
async-signal-safe, just like a signal handler today. All you've done is
tweak the precise location of the signal stack and made it harder for
the handler to inspect any relevant thread state.
Sure, you could handle the signal out-of-process somehow, but at that
point, you've just reinvented ptrace.
> This isn't done because creating thread contexts just to handle signals
> in single thread application is too expensive.
It's also because the thread mechanism you're suggesting wouldn't
actually deliver any benefits.
More information about the Libc-alpha
mailing list