This is the mail archive of the libc-alpha@sourceware.org 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-, Signal- and Cancellation-safety documentation


On Mar 26, 2013, Rich Felker <dalias@aerifal.cx> wrote:

> On Tue, Mar 26, 2013 at 01:49:20AM -0300, Alexandre Oliva wrote:

>> One of the stumbling blocks I ran into was that setlocale (unlike
>> uselocale) may change the global locale object and, even though the
>> modification of this object is guarded by a rwlock, most uses are not.

> I know your work is just documenting existing practice, but unless
> there's a clause in POSIX (and now, C11 too, since C11 has threads)
> which allows this, I think the underlying issue should be fixed.

Yup.  One of the reasons for bringing this up was to discuss how/whether
we were going to fix that.

> The cleanest fix I can envision would be atomically replacing the
> pointer to the locale object once the new one is prepared.

If it was a single pointer, that would indeed be a good course of
action, but there are multiple pointers that may each change
independently *or* with a single setlocale call.  Plus, we modify a
global object, which gets implicitly passed to some functions which read
from it often without expecting that it might change.

Indeed, besides the ctype functions that don't take a locale object, and
use the active one (which might be the global locale object), there are
those that take a pointer to a locale object, and if this object is the
global locale object, it may change from under them.  Even callers of
these functions that attempt to read locale properties once as they
start are toast if they also call any of these interfaces, for then the
early-reading (presumably for internal consistency) won't guarantee that
the callees use the same locale information.

And then, all the cases that caught my attention actually relied on
different categories, that may change independently, so we can't really
do away with the rwlocking for those.

> Per POSIX, setlocale is thread-safe.

Yeah.  I've avoided looking at the specs to not guide my conclusions
about how safe functions are based on how safe they ought to be, but
this one bit was brought to my attention before.

> I'm a bit confused here. With or without fsetlocking having been used,
> all of stdio is thread-safe as long as the same FILE is not acted upon
> by more than one thread at a time. fsetlocking pertains to whether the
> _data object_ (the FILE) is safe to operate upon from multiple
> threads, not whether the stdio functions are thread-safe. Do you have
> a way to represent this distinction?

I don't see that the definition of thread-safety in the relevant
standards makes room for this distinction.  I've drawn the line on
whether the object the functions operate on are opaque to the callers
(like streams) or controlled by them (say strings).  After all, strcpy
is not unsafe just because someone might change a string from under it
on another thread (right?), but if a stream operation can be messed up
by another thread operating on the same stream, that makes the operation
thread-unsafe to me.  Because fsetlocking by_caller disables the
internal safety that a number of functions offer by default, it follows
that either fsetlocking must be marked as unsafe to use in multi-thread
programs, or the other functions whose behavior is affects are.  I don't
see how to regard all of them as âunconditionallyâ safe.

>> therefore well-defined and safe.  In the end, fclose turned out to be
>> AS-Unsafe for other reasons (a non-recursive gconv mutex that could
>> self-deadlock), but the rationale, if agreed by the community as sound,
>> may be reused in other settings.

> Doesn't the freeing make it unsafe?

Why would it?  (given that calling any other stream function, including
fclose, on a stream object for which you've already called fclose,
invokes undefined behavior, which IMHO sets a requirement for calling
fclose and all these other functions that would suffice to make fclose
safe in this regard)

> It's basically impossible to be AC safe without simply disabling async
> cancellation before doing your work then reenabling it afterwards.

I don't quite agree with that; I don't see that it would be impossible
for a suitable cleanup region to start right after the atomic operation
that sets a lock, for example, but I don't see that we have means to
express that in C with a sufficiently level of detail to guarantee
unambiguous safety.

-- 
Alexandre Oliva, freedom fighter    http://FSFLA.org/~lxoliva/
You must be the change you wish to see in the world. -- Gandhi
Be Free! -- http://FSFLA.org/   FSF Latin America board member
Free Software Evangelist      Red Hat Brazil Compiler Engineer


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