This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: Thread-, Signal- and Cancellation-safety documentation
- From: Florian Weimer <fweimer at redhat dot com>
- To: Alexandre Oliva <aoliva at redhat dot com>
- Cc: Torvald Riegel <triegel at redhat dot com>, KOSAKI Motohiro <kosaki dot motohiro at gmail dot com>, Rich Felker <dalias at aerifal dot cx>, libc-alpha <libc-alpha at sourceware dot org>
- Date: Fri, 31 May 2013 10:46:27 +0200
- Subject: Re: Thread-, Signal- and Cancellation-safety documentation
- References: <orppym7okv dot fsf at livre dot home> <20130326064347 dot GL20323 at brightrain dot aerifal dot cx> <515AB073 dot 9000500 at redhat dot com> <20130402134325 dot GO20323 at brightrain dot aerifal dot cx> <CAHGf_=q=2sM0C5kLazsVWiRfRvO0NX-sDRX2-SfoJkkCix9vzQ at mail dot gmail dot com> <1368788825 dot 3054 dot 3182 dot camel at triegel dot csb> <ora9nrh1cz dot fsf at livre dot home> <51A328F0 dot 5020003 at redhat dot com> <ora9ncqlg4 dot fsf at livre dot home>
On 05/30/2013 10:09 PM, Alexandre Oliva wrote:
On May 27, 2013, Florian Weimer <fweimer@redhat.com> wrote:
On 05/19/2013 09:31 AM, Alexandre Oliva wrote:
On May 17, 2013, Torvald Riegel <triegel@redhat.com> wrote:
* There's no clear definition of whether "thread-safe" is about...
There's a clear definition of the specified behavior for each function,
so âfunction F is safe to callâ ought to mean âF behaves as specifiedâ.
But this is clearly wrong for functions such as chdir(). You really
shouldn't call them in multi-threaded programs, but they still work
exactly as specified.
And, indeed, POSIX states chdir is thread-safe. And why shouldn't it
be? What consistency guarantees do concurrent calls of chdir() violate?
From the standard perspective? None. But it still breaks modularity.
Saying you shouldn't call it is pushing it a bit. Say, if all
filesystem operations use full pathnames or *at() calls, why not? If
one thread alone is responsible for filesystem operations, and it is the
one that calls chdir(), why not?
There's no fgetxattrat, so it is tempting to emulate the missing
opportunity to specify AT_SYMLINK_NOFOLLOW using chdir and lgetxattr.
If you do this in library code, it is not thread-safe at all, even
though you only use functions which are defined as thread-safe.
Sure, if two threads call it concurrently, you can't predict which one
ends up as the cwd for the process, but that's just as impredictable as
the result when two threads call write concurrently, or rename
concurrently from or to the same pathname. But you wouldn't say
multi-threaded programs shouldn't call write or rename, would you?
That's because the immediate caller can ensure that it has exclusive
access to the resource (or determine that the race is benign), This is
impossible to do with process-global attributes such as the current
directory.
Avoiding trouble requires a bit of discipline, in some cases more than
in others. Thread-safe doesn't mean trouble-free, nor does it mean no
possibility of creating race conditions, nor does it guarantee
fully-predictable outcomes. It's much, much weaker than that.
More and more code is put into libraries, and multi-threaded
applications are now common. That's why I think that we should caution
programmers about chdir and similar functions which change global
process attributes. glibc's compliance with thread safety requirements
in the standard should be of little concern to them, they need something
that works in their situation (which is, I believe, increasingly library
code).
--
Florian Weimer / Red Hat Product Security Team