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>