This is the mail archive of the
mailing list for the glibc project.
Re: thread safety level of fwide
- From: Rich Felker <dalias at libc dot org>
- To: Torvald Riegel <triegel at redhat dot com>
- Cc: Alexandre Oliva <aoliva at redhat dot com>, MaShimiao <mashimiao dot fnst at cn dot fujitsu dot com>, Carlos O'Donell <carlos at redhat dot com>, libc-help at sourceware dot org, GLIBC Devel <libc-alpha at sourceware dot org>
- Date: Thu, 20 Nov 2014 23:10:36 -0500
- Subject: Re: thread safety level of fwide
- Authentication-results: sourceware.org; auth=none
- References: <546C4388 dot 1090209 at cn dot fujitsu dot com> <or61eborsv dot fsf at free dot home> <1416488347 dot 1771 dot 26 dot camel at triegel dot csb>
On Thu, Nov 20, 2014 at 01:59:07PM +0100, Torvald Riegel wrote:
> On Wed, 2014-11-19 at 18:32 -0200, Alexandre Oliva wrote:
> > On Nov 19, 2014, MaShimiao <email@example.com> wrote:
> > > After reading it's source code, I think it should be marked with race:stream.
> > > The reasoning is fwide() uses fp several times inside without holding the lock over all of them.
> > > How do you think about that?
> > The uses of fp, although technically racy, are well-defined, because of
> > the way stream orientation works: once it's decided, it never changes,
> > so it is safe to test, before taking a lock, whether it is already
> > decided and use the settled value if so.
> We have to consider two things here: data races on the value itself, and
> data races on memory locations that have are related to the value.
> When we change the accesses to fp->_mode to memory_order_relaxed
> atomics, then there's no race on _mode anymore (and we should do that at
> least). However, if a certain _mode value logically relates to anything
> of what _IO_fwide does internally while holding the lock, then there's
> likely a data race on that.
> I've just glanced at a few pieces of code, but this may be a case of an
> incorrect double-checked locking implementation. Whether that is the
> case depends on whether there is an invariant between x and mode in the
> example below (this uses C11-like atomic operations, and assumes the C11
> memory model):
As a function that operates on a FILE, fwide is required by POSIX to
behave as if it acquires the internal recursive mutex on the target
In particular, if another thread has the FILE locked by flockfile,
fwide cannot return until that other thread unlocks the file, and this
acquisition and release of the internal mutex synchronizes memory
between these two threads.
If glibc is eliding the locking here, it's non-conforming.