This is the mail archive of the mailing list for the glibc project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: thread safety level of fwide

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 <> 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
file. See:

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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]