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: KOSAKI Motohiro <kosaki dot motohiro at gmail dot com>
- To: libc-alpha at sourceware dot org
- Cc: kosaki dot motohiro at gmail dot com
- Date: Wed, 27 Mar 2013 18:10:07 -0400
- Subject: Re: Thread-, Signal- and Cancellation-safety documentation
- References: <orppym7okv dot fsf at livre dot home>
(3/26/13 12:49 AM), Alexandre Oliva wrote:
> I've (not so) recently started working on documenting these safety
> properties of glibc functions. I believe now have enough of a patchset
> to get the discussion on form and content started.
Great work!
I would like to join reviewing this.
> I introduced a few macros to document these properties. I envision that
> they might expand differently in info and pdf docs, but currently
> they're the same. Some of the *unsafe macros expand to nothing, because
> unsafe is the default, but I wanted to document that the property was
> actually assessed and what makes the function unsafe (in comments in the
> manual sources, but not in the manual formatted output).
>
> 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.
> As a result, many functions were marked as unsafe, with âglocaleâ as the
> reason. More recently, talking to Carlos about the consequences of this
> and debating how best to approach the need for some functions to be
> MT-Safe in spite of setlocale, we decided to document setlocale itself
> as unsafe, so that calling it after starting threads was documented as
> problematic. Then, we could document the fast-path functions as MT-Safe
> even though they don't bother with locking.
As Rich said, this is MT-safe from point of POSIX view. To clarify, I'd like
to explain how proprietary UNIX do.
Solaris have three MT-safe leve, MT-safe, MT-unsafe, and MT-safe with exceptions.
MT-safe mean "yeah, you can use this function w/o any wrroy. it's completely safe
for multi thread". MT-unsafe mean "don't use this if you have multi thread. we have
better alternative functions". MT-safe w/ exception mean "you can use this under multi
thread environment, but additional thread specific coding rule may apply".
And then, setlocale() is marked as "MT-safe with exceptions" and describe glocale thing
by natural language verbosely. and ctype(3) are also marked as MT-safe with exceptions
and say "see setlocale" shortly.
The idea is clear. MT-safe with exceptions mean the implementation don't break any
standard conformance (i.e. setlocale() vs setlocale() is completely thread safe),
but even though, you need some care when using under MT.
I think to mark MT-unsafe bring developrs confusions. they might think glibc don't
keep conformance.
> A similar âsolutionâ was used for fsetlocking: since it may disable
> internal locking, it would render several functions MT-Unsafe (and also
> cause them to release locks they didn't take, or take locks and never
> release them). By declaring fsetlocking itself MT-Unsafe, we avoid
> these problems (since then calling it after starting threads invokes
> undefined behavior), without making every function that optionally takes
> care of internal locking MT-Unsafe. It would be possible, however, to
> make fsetlocking MT-Safer :-) by changing it hold the stream's recursive
> lock regardless of internal-locking status (to make sure all threads
> that are using the stream complete the operation underway, be it guarded
> by internal locking, be it explicit external locking--use without either
> is undefined). This wouldn't make it AS-Safe, which would require all
> functions that optionally take the lock to load the status only once
> into an automatic variable, and use it to decide whether to take and
> release the lock, or neither, rather than re-reading the setting that
> may have been modified in a signal handler. This is fixable but
> cumbersome and possibly not worth it, so I didn't implement this
> change.
ditto.
MT w/ exceptions would be best to me.
And also,
> @deftypefun int printf (const char *@var{template}, @dots{})
> +@safety{@mtunsafe{glocale-revisit}@asunsafe{badstream, glocale-revisit}@acunsafe{memleak, lockleak, badstream}}
I believe printf should be MT-safe w/ exceptions or special.
It has wild industrial consensus that it is thread safe and more over no better alternative.
So, I believe we shouldn't completely discourage to use printf. and nit, printf should refer
register_printf_function. it also break thread safety.
> @deftypefun int sprintf (char *@var{s}, const char *@var{template}, @dots{})
>+@safety{@mtunsafe{glocale-revisit}@asunsafe{glocale-revisit}@acsafe{memleak}}
Solaris mark sprintf and snprintf mark as AS-safe (w/ exceptions). and it is
already in use from multiple applications.
I don't think there is no good reason to discourage to use sprintf.
> @deftypefun int feof_unlocked (FILE *@var{stream})
>+@safety{@mtsafe{}@assafe{}@acsafe{}}
>+@c There isn't much of a thread unsafety risk in reading a flag word and
>+@c testing a bit in it.
This is another interesting part to me. feof_unlocked is thread safe under
many OSs. However, as far as I know, all OSs mark it as MS-unsafe because
manual describe the interface promising, not current implementations.
But, hm, ok. this is just nit. I don't think this promise keep so hard.
> @deftypefun {FILE *} fmemopen (void *@var{buf}, size_t @var{size}, const char *@var{opentype})
> +@safety{@mtsafe{}@assafe{}@acsafe{memleak}}
I doubt this is assafe. because
1. fmemopen uses malloc internally.
2. _IO_link_in touch global io list and it's not recursive call safe.
In general, foobar_open() never be AS-safe. But please let me know if I'm
missing something.
Other than that, your patchs are definitely great work and covers wide
functions. thanks a lot.