Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 2 Oct 2017 11:03:49 +0200
From:      Erwan Legrand <freebsd@erwanlegrand.com>
To:        Matthias Apitz <guru@unixarea.de>, FreeBSD Questions <freebsd-questions@freebsd.org>
Subject:   Re: no dead-lock when signal handler calls localtime_r() on FreeBSD,  but on Linux
Message-ID:  <CA%2B4G5KZv7NR-jDsuiM5hw9E_s_NYCs2psktYxJY2rOZR5T9cYQ@mail.gmail.com>
In-Reply-To: <20171002071000.GA1373@sh4-5.1blu.de>
References:  <20171002063425.GA21552@sh4-5.1blu.de> <102e950a-f3f2-bff1-1025-d5e757ee793b@gmx.com> <20171002071000.GA1373@sh4-5.1blu.de>

next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, Oct 2, 2017 at 9:10 AM, Matthias Apitz <guru@unixarea.de> wrote:
> El d=C3=ADa Monday, October 02, 2017 a las 09:57:51AM +0300, Yuri Pankov =
escribi=C3=B3:
>> On Mon, 2 Oct 2017 08:34:26 +0200, Matthias Apitz wrote:
>> >I'm on the way clarifying a deadlock-issue we face on Linux when localt=
ime_r()
>> >is called in a signal-handler funtion. If you compile the code attached
>> >below with gcc on Linux, the code gives what one deserves: a dead-lock
>> >when Ctrl-C is pressed.
>>
>> Why? I don't see anything explicitly stating that localtime_r() is
>> async-signal-UNsafe.
>
> Because, as I said, it is not in the list of
>
>      The following functions are either reentrant or not interruptible by
>      signals and are async-signal safe.  Therefore applications may invok=
e
>      them, without restriction, from signal-catching functions or from a =
child
>      process after calling fork(2) in a multi-threaded process:
>
> in the man page sigactio(2).

So what?

Calling async-safe functions in signal handlers will not by itself
trigger a bug. (Unless there is a bug in the implementation.) That is
what a guarantee that async-safe functions (and standards) give.

Assuming that calling in a signal handler functions which are not
labeled as async-safe by some standard will reproducibility trigger a
bug is faulty logic. Doing so *may* trigger a bug, but that is *not* a
guaranteed behavior.

localtime_r() is guaranteed to be thread-safe. It is not guaranteed to
be async-safe. This suggest that the function might not be truly
reentrant. It is only guaranteed to be reentrant with regard to thread
safety. Async-safety requires reentrancy in a strictest sense.

The implementation of localtime_r() in glibc is a good example as it
calls a function named __tz_convert() which itself acquires a lock
which makes it unsuitable for use within a signal handler.

In the case of FreeBSD, a read-write lock is used and locatime_r()
locks it as a reader. As multiple readers are allowed, this does not
block in your case. Still, calling localtime_r() in a signal handler
will block if the lock is acquired by a writer.

Do not call async-unsafe functions in signal handlers. *Just don't!*



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CA%2B4G5KZv7NR-jDsuiM5hw9E_s_NYCs2psktYxJY2rOZR5T9cYQ>