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: [MTASCsft PATCH WIP5 01/33] Multi Thread, Async Signal and Async Cancel safety documentation: intro


On Nov 20, 2013, Alexandre Oliva <aoliva@redhat.com> wrote:

> Here's an updated 01/33, revised so as to reflect all the feedback I got
> (thanks for the reviews!), but not the issues in which my replies ended
> with questions or other indications that the issue is still pending.

> After the full patch, I include a diff between the results of applying
> the v5 patch and the revised patch.

Here's another update, with updated versions of both diffs mentioned
above, plus a diff from the previous patch posted on Nov 20.  It does
*not* introduce the new keywords I proposed, nor the macros that are
going to be used to reference them.  I'm waiting for an ack from Joseph
before I proceed to implement such a major change.

Multi Thread, Async Signal and Async Cancel safety documentation: intro

From: Alexandre Oliva <aoliva@redhat.com>

for  ChangeLog

	* manual/macros.texi: Introduce macros to document multi
	thread, asynchronous signal and asynchronous cancellation
	safety properties.
	* manual/intro.texi: Introduce the properties themselves.
---
 manual/intro.texi  |  557 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 manual/macros.texi |   42 ++++
 2 files changed, 599 insertions(+)

diff --git a/manual/intro.texi b/manual/intro.texi
index deaf089..97712f2 100644
--- a/manual/intro.texi
+++ b/manual/intro.texi
@@ -159,6 +159,15 @@ Utilities standard} (POSIX.2) are also implemented in @theglibc{}.
 These include utilities for dealing with regular expressions and other
 pattern matching facilities (@pxref{Pattern Matching}).
 
+@menu
+* POSIX Safety Concepts::       Safety concepts from POSIX.
+* Unconditional Unsafety::      Features that make functions
+                                 unconditionally unsafe.
+* Avoidable Unsafety::          Features that make functions unsafe,
+                                 but that can be worked around.
+* Other Safety Remarks::        Additional safety features and remarks.
+@end menu
+
 @comment Roland sez:
 @comment The GNU C library as it stands conforms to 1003.2 draft 11, which
 @comment specifies:
@@ -172,6 +181,554 @@ pattern matching facilities (@pxref{Pattern Matching}).
 @comment <wordexp.h> (not yet implemented)
 @comment confstr
 
+@node POSIX Safety Concepts, Unconditional Unsafety, , POSIX
+@subsubsection POSIX Safety Concepts
+@cindex POSIX Safety Concepts
+
+The safety properties of @glibcadj{} functions, documented as MT-, AS-
+and AC- -Safe and -Unsafe are assessed according to the criteria set
+forth in the POSIX standard for Thread-, Async-Signal- and Async-Cancel-
+safety.
+
+Intuitive definitions of these properties, attempting to capture the
+meaning of the standard definitions, follow:
+
+@itemize @bullet
+
+@item
+@cindex MT-Safe
+MT-Safe functions are safe to call in the presence of other threads.  MT
+stands for Multi Thread.
+
+A function being MT-Safe does not imply any form of synchronization, nor
+that any combination of calls of MT-Safe functions would be regarded as
+MT-Safe.  For example, having a thread call two MT-Safe functions one
+right after the other does not guarantee behavior equivalent to atomic
+execution of a combination of both functions, since concurrent calls in
+other threads may cause behavior to diverge.
+
+In some cases, even expanding MT-Safe functions inline could cause
+combinations to become MT-Unsafe due to reordering that this could
+enable; this is never the case of @glibcadj{} functions defined in
+user-visible headers, because these are meant to be inlined, but it may
+be for functions that are exported by @glibcadj{} shared libraries;
+whole-program optimizations that might inline functions across library
+interfaces might expose this sort of problem, so performing inlining
+across the @glibcadj{} interface is not recommended, nor is the
+documented MT-Safety status guaranteed under such arrangements.
+
+@item
+@cindex AS-Safe
+AS-Safe functions are safe to call from asynchronous signal handlers.
+AS stands for Asynchronous Signal.
+
+Many functions that are AS-Safe may set @code{errno}, or modify the
+floating-point environment, because their doing so does not make them
+unsuitable for use in signal handlers.  However, programs could
+misbehave should asynchronous signal handlers modify this thread-local
+state, and the signal handling machinery cannot be counted on to
+preserve it.  Therefore, signal handlers that call functions that may
+set @code{errno} or modify the floating-point environment @emph{must}
+save their original values, and restore them before returning.
+
+@item
+@cindex AC-Safe
+AC-Safe functions are safe to call when asynchronous cancellation is
+enabled.  AC stands for Asynchronous Cancellation.
+
+@item
+@cindex MT-Unsafe
+@cindex AS-Unsafe
+@cindex AC-Unsafe
+MT-Unsafe, AS-Unsafe, AC-Unsafe functions are not safe to call within
+the contexts described above.  Calling them within such contexts invokes
+undefined behavior.
+
+Functions not explicitly documented as Safe should be regarded as
+Unsafe.
+
+@end itemize
+
+By ``safe to call'', we mean that, as long as the program does not
+invoke undefined or unspecified behavior, the called functions will
+behave as documented, and they will not cause any other functions to
+deviate from their documented behavior.
+
+Although we strive to abide by the standards, in some cases our
+implementation is safe even when the standard does not demand safety,
+and in other cases our implementation does not meet the standard safety
+requirements.  At this point, we document the result of an assessment of
+the properties of our implementation, so the safety documentation in
+this manual is not to be regarded as a promise of future behavior: in
+future releases, functions that are documented as safe may become
+unsafe, and safety constraints may be removed or introduced.  We
+envision turning the results of the assessment into a set of promises as
+stable as our interfaces, but we are not there yet.
+
+@node Unconditional Unsafety, Avoidable Unsafety, POSIX Safety Concepts, POSIX
+@subsubsection Unconditional Unsafety
+@cindex Unconditional Unsafety
+
+Functions that are unsafe to call in certain contexts are annotated with
+keywords that document their features that make them unsafe to call:
+
+@itemize @bullet
+
+@item @code{staticbuf}
+@cindex staticbuf
+
+Functions annotated with @code{staticbuf} use internal objects in ways
+that may cause concurrent calls to interfere destructively.  In this
+case internal does not mean the objects are not exposed to callers, just
+that they are not supplied by callers (contrast with the @code{uunguard}
+and @code{xguargs} keywords).
+
+These functions are all MT-Unsafe and AS-Unsafe.  However, many of them
+offer reentrant variants for MT-Safe and, in some cases, AS-Safe use.
+
+In many of these cases, the static buffer is only used to hold a return
+value; in a few of these, such as @code{tmpnam}, the use of the internal
+buffer can be avoided by passing the buffer as an argument, which makes
+the call MT-Safe and AS-Safe.
+
+
+@item @code{lockleak}
+@cindex lockleak
+
+Functions annotated with @code{lockleak} may leak locks if asynchronous
+thread cancellation interrupts their execution.
+
+While the problem is similar to that of file descriptors, in that there
+is not any atomic interface to lock and take note of the need for
+unlocking in a cleanup, or to unlock and take note that there is no
+longer such a need, the problem posed by lock leaks is far more serious:
+when a file descriptor or a piece of memory is leaked, it becomes
+inaccessible and subsequent attempts to allocate a file descriptor or
+some memory will just use another resource.  However, once a lock is
+left taken, attempts to take that lock will block indefinitely.
+(Recursive locks will only block other threads, and read locks will only
+block writer threads, but the point still holds in general).
+
+For the reasons above, functions that leak locks are all AC-Unsafe.
+
+
+@item @code{selfdeadlock}
+@cindex selfdeadlock
+
+Functions marked with @code{selfdeadlock} take a non-recursive lock to
+ensure MT-Safety while modifying data structures guarded by the lock.
+
+If such a function is called by a signal handler that interrupted
+another such function that took the lock, the result is a deadlock.
+
+Blocking asynchronous signal delivery while calling such functions is
+the only safe way to avoid a deadlock if any signal handler might need
+to call them.
+
+
+@item @code{asynconsist}
+@cindex asynconsist
+
+Functions marked with @code{asynconsist} take a recursive lock to ensure
+MT-Safety while accessing or modifying data structures guarded by the
+lock.
+
+If such a function is called by a signal handler that interrupted
+another such function that took the lock, both may misbehave for
+observing inconsistent (partially updated or cached) data structures.
+
+Blocking asynchronous signal delivery while calling such functions is
+the only safe way to avoid the misbehavior that may ensue if any signal
+handler might need to call them.
+
+
+@item @code{incansist}
+@cindex incansist
+
+Functions marked with @code{incansist} modify data structures in a
+non-atomic way.
+
+If such a function is asynchronously cancelled, it may leave the data
+structure in a partially updated, inconsistent state.  Subsequent uses
+of the data structure may misbehave.
+
+Disabling asynchronous cancellation while calling such functions is the
+only safe way to avoid the misbehavior if the thread is cancelled while
+the function is running.
+
+@c A special case, probably not worth documenting separately, involves
+@c reallocing, or even freeing pointers.  Any case involving free could
+@c be easily turned into an ac-safe memleak by resetting the pointer
+@c before releasing it; I don't think we have any case that calls for
+@c this sort of fixing.  Fixing the realloc cases would require a new
+@c interface: instead of @code{ptr=realloc(ptr,size)} we'd have to
+@c introduce @code{acsafe_realloc(&ptr,size)} that would modify ptr
+@c before releasing the old memory.  The ac-unsafe realloc could be
+@c implemented in terms of an internal interface with this semantics
+@c (say __acsafe_realloc), but since realloc can be overridden, the
+@c function we call to implement realloc should not be this internal
+@c interface, but another internal interface that calls __acsafe_realloc
+@c if realloc was not overridden, and calls the overridden realloc with
+@c async cancel disabled.  --lxoliva
+
+
+@item @code{asmalloc}
+@cindex asmalloc
+
+Functions marked with @code{asmalloc} perform memory allocation or
+deallocation with the @code{malloc}/@code{free} family of functions,
+thus implying all of the keywords of these functions.
+
+If heap management functions are interrupted by asynchronous signals,
+and the signal handlers attempt to perform memory allocation or
+deallocation of their own, they may encounter heap data structures in a
+partially updated state, and the interrupted calls may malfunction
+because of the changes made within the signal handler.
+
+
+@item @code{asi18n}
+@cindex asi18n
+
+Functions marked with @code{asi18n} call internationalization functions
+of the @code{gettext} family, thus implying all of the keywords
+of @code{gettext}.
+
+
+@item @code{shlimb}
+@cindex shlimb
+
+Functions marked with @code{shlimb} use the dynamic loader to bring in
+additional code modules.  This involves opening files, mapping them into
+memory, allocating additional memory, resolving symbols, applying
+relocations and more, all of this while holding internal dynamic loader
+locks.
+
+The locks are enough for these functions to be AS- and AC-Unsafe, but
+other issues may arise; the safety documentation of @code{dlopen}, when
+available, shall list all the keywords implied by this one.
+
+
+@item @code{uplugin}
+@cindex uplugin
+
+Functions annotated with @code{uplugin} may run code from plugins that
+may be external to @theglibc{}.  Such plug-in functions are assumed to
+be MT-Safe, AS-Unsafe and AC-Unsafe.
+
+Examples of such plugins are stack unwinding libraries and nss
+back-ends.
+
+
+@end itemize
+
+
+@node Avoidable Unsafety, Other Safety Remarks, Unconditional Unsafety, POSIX
+@subsubsection Avoidable Unsafety
+@cindex Avoidable Unsafety
+
+For some features that make functions unsafe to call in certain
+contexts, there are known ways to avoid the safety problem other than
+refraining from calling the function altogether.  The keywords that
+follow refer to such features, and each of their definitions indicate
+how the whole program needs to be constrained in order to remove the
+safety problem indicated by the keyword.  Only when all the reasons that
+make a function unsafe are observed and addressed by applying the
+documented constraints does the function become safe to call in a
+context.
+
+@itemize @bullet
+
+@item @code{oncesafe}
+@cindex oncesafe
+
+Functions marked with @code{oncesafe} use the internal @code{libc_once}
+machinery or similar to initialize internal data structures.
+
+If a signal handler interrupts such an initializer, and calls any
+function that also performs @code{libc_once} initialization, it will
+deadlock if the thread library is linked in.
+
+Furthermore, if an initializer is partially complete before it is
+canceled or interrupted by a signal whose handler requires the same
+initialization, some or all of the initialization may be performed more
+than once, leaking resources or even result in corrupt internal data
+structures.
+
+Applications that need to call functions marked with @code{oncesafe}
+should ensure the initialization is performed before configuring signal
+handlers or enabling cancellation, so that the AS- and AC-Safety issues
+related with @code{libc_once} do not arise.
+
+
+@item @code{1stcall}
+@cindex 1stcall
+
+Functions marked with @code{1stcall} perform MT-unsafe initialization
+when they are first called.  
+
+Calling such a function at least once in single-threaded mode removes
+this specific cause for the function to be regarded as MT-Unsafe.  If no
+other cause for that remains, the function can then be safely called
+after other threads are started.
+
+
+@item @code{uunguard}
+@cindex uunguard
+
+Functions marked with @code{uunguard} modify non-atomically arguments or
+global objects that other functions access without synchronization.  A
+consequence of regarding modifiers of these objects as unsafe is that
+the covered objects can be regarded as constant (subject to the
+observation of safety constraints), so that all readers can be
+considered safe in this regard.
+
+In order to avoid the safety issues posed by these unguarded accesses,
+callers must guard calls to @emph{all} readers and writers of the
+affected objects with something equivalent to a @code{rwlock}, i.e.,
+writers must get exclusive access, while multiple concurrent readers may
+be allowed.
+
+Unguarded users of the global locale object modified by @code{setlocale}
+are marked with @code{glocale}.
+
+Unguarded users of the global environment are marked with
+@code{envromt}.
+
+Unguarded users of the @code{printf} extension objects modified by
+@code{register_printf_function} are the entire family of printf
+functions.
+
+Unguarded users of file streams configured with @code{__fsetlocking} for
+locking by the caller are the entire family of stdio functions.
+
+
+@item @code{xguargs}
+@cindex xguargs
+
+Functions marked with @code{xguargs} may use or modify objects passed
+(indirectly) as arguments, without any guards to guarantee consistency.
+To ensure MT- and AS-Safe behavior, callers must ensure that the objects
+passed in are not accessed or modified concurrently by other threads or
+signal handlers.
+
+This mark is only applied with regard to an object when the
+@code{uunguard} mark is not applied because of the same object, and the
+object is opaque or not intended to be modified by code outside of
+@theglibc{}.  The rationale is that, for such an object, there could be
+a reasonable (but unsatisfied) expectation that the library would take
+care of synchronization to modify the object.
+
+Strings, structs and other object types whose members are meant to be
+modified by users are @emph{not} marked with @code{xguargs}.
+User-initiated inspection and modification are already constrained by
+the standard synchronization requirements, plus any other type- or
+object-specific additional requirements, such as user-initiated locking
+of streams configured to avoid internal locking.  (File streams happen
+to be opaque types, but the principle stands.)  Users must satisfy these
+requirements regardless of whether modifications are coded by users or
+the library, so the mark would be redundant.  The mark, when present,
+clarifies that users remain responsible for satisfying any
+synchronization requirements when calling the marked function, because
+the library will not take care of them on its own.
+
+
+@item @code{tempchwd}
+@cindex tempchwd
+
+Functions marked with @code{tempchwd} may temporarily change the current
+working directory during their execution, which may cause relative
+pathnames to be resolved in unexpected ways in other threads or within
+asynchronous signal or cancellation handlers.
+
+This is not enough of a reason to mark so-marked functions as MT-Unsafe,
+but when this behavior is optional (e.g., @code{nftw} with
+@code{FTW_CHDIR}), avoiding the option in multi-threaded programs may be
+a good alternative to using full pathnames or file descriptor-relative
+(e.g. @code{openat}) system calls.
+
+
+@item @code{tempsig}
+@cindex tempsig
+
+Functions marked with @code{tempsig} may temporarily install signal
+handlers for internal purposes, which may interfere with other uses of
+those signals.  
+
+This makes such functions MT-Unsafe and AS-Unsafe to begin with.  If
+this note appears as an AC-Safety issue, however, the problem is more
+complex: the temporarily-installed signal handler may remain in place if
+the thread is cancelled.  Safety for all these situations can be
+achieved by refraining from using the specific signals while calling the
+function.
+
+
+@item @code{tempterm}
+@cindex tempterm
+
+Functions marked with @code{tempterm} may temporarily change the
+terminal settings.
+
+This would not be enough of a reason to mark so-marked functions as
+MT-Unsafe, but the recommended mode to modify terminal settings is to
+call @code{tcgetattr}, modify some flags, and then call
+@code{tcsetattr}.  Functions marked with @code{tempterm} do that, so
+they leave a window in which changes made by other threads are lost.
+
+It is thus advisable for applications using the terminal to avoid
+concurrent interactions with it, more so if they expect different
+terminal modes.
+
+If this mark appears as an AC-Safety note, it means the function may
+also fail to restore the original terminal mode in case of asynchronous
+cancellation.
+
+
+@item @code{stimer}
+@cindex stimer
+
+Functions marked with @code{stimer} use the @code{alarm} function or
+similar to set a time-out for a system call or a long-running operation.
+In a multi-threaded program, there is a risk that the time-out signal
+will be delivered to a different thread, thus failing to interrupt the
+intended thread.
+
+Keeping @code{SIGALRM} blocked on all threads, and refraining from
+concurrently calling functions that may set up such timers, is the only
+way to avoid this safety issue.
+
+
+@end itemize
+
+
+@node Other Safety Remarks, , Avoidable Unsafety, POSIX
+@subsubsection Other Safety Remarks
+@cindex Other Safety Remarks
+
+Additional keywords may be attached to functions, indicating features
+that do not make a function unsafe to call, but that may need to be
+taken into account in certain classes of programs:
+
+@itemize @bullet
+
+@item @code{glocale}
+@cindex glocale
+
+In threads that have not overridden the thread-local locale object by
+calling @code{uselocale}, calling functions annotated with
+@code{glocale} concurrently with @code{setlocale} may cause the
+functions to behave in ways that do not correspond to either the
+previous or the subsequent global locale.
+
+Although the @code{setlocale} function modifies the global locale object
+while holding a lock, @code{glocale}-annotated functions may access this
+global object multiple times, without any measures to ensure it does not
+change while it is in use.
+
+Each of these unprotected uses will use either the previous or the
+subsequent locale information, so they will not cause crashes or access
+to uninitialized, unmapped or recycled memory.  However, sometimes
+cached local information is used whereas in other cases, the locale
+object is accessed anew; thus, concurrent changes to the global locale
+object may cause these functions to behave in unexpected ways (i.e.,
+behavior that is not possible if @code{setlocale} and the so-annotated
+functions would have been executed in some sequential order).
+
+The @code{glocale} constraint indicates functions are only safe to call
+if the effective thread-local locale is not the global locale object
+(because it was overridden with @code{uselocale}).  Failing that,
+@code{setlocale} should not be called while these functions are active.
+
+
+@item @code{envromt}
+@cindex envromt
+
+Functions marked with @code{envromt} access the environment with
+@code{getenv} or similar, requiring the environment to be effectively
+read-only for MT-Safe operation.
+
+Environment-modifying functions do not protect in any way against
+concurrent modifications or access.  Calling @code{envromt}-marked
+functions concurrently with @code{setenv}, @code{putenv},
+@code{unsetenv} or direct modifications of the global environment data
+structures is ill-advised; external concurrency control must be
+introduced by callers of these environment-modifying and
+@code{envromt}-marked functions.
+
+Functions that modify the environment are also marked with
+@code{envromt}, but they are not MT-Safe for the reasons above.  Since
+all environment-modifying functions are MT-Unsafe, functions that only
+access the environment are marked as MT-Safe when no other safety issue
+applies.
+
+
+@item @code{fdleak}
+@cindex fdleak
+
+Functions annotated with @code{fdleak} may leak file descriptors if
+asynchronous thread cancellation interrupts their execution.
+
+Functions that allocate or deallocate file descriptors will generally be
+marked as such, because even if they attempted to protect the file
+descriptor allocation and deallocation with cleanup regions, allocating
+a new descriptor and storing its number where the cleanup region could
+release it cannot be performed as a single atomic operation, just like
+releasing it and taking it out of the data structure normally
+responsible for releasing it cannot be performed atomically, always
+leaving a window in which the descriptor cannot be released because it
+was not stored in the cleanup handler argument yet, or in which it was
+already taken out of it before releasing it in the normal flow (we
+cannot keep it there because, in case of cancellation, we would not be
+able to tell whether it was already released, and the same number could
+have been already assigned to another descriptor by another thread, so
+we could not just release it again).
+
+Such leaks could be internally avoided, with some performance penalty,
+by temporarily disabling asynchronous thread cancellation.  However,
+since callers of allocation or deallocation functions would have to do
+this themselves, to avoid the same sort of leak in their own layer, it
+makes more sense for the library to assume they are taking care of it
+than to impose a performance penalty that is redundant when the problem
+is solved in upper layers, and insufficient when it is not.
+
+This remark by itself does not cause a function to be regarded as
+AC-Unsafe.  However, cumulative effects of such leaks may pose a
+problem for some programs.  If this is the case, suspending asynchronous
+cancellation for the duration of calls to such functions is recommended.
+
+
+@item @code{memleak}
+@cindex memleak
+
+Functions annotated with @code{memleak} may leak memory if asynchronous
+thread cancellation interrupts their execution.
+
+The problem is similar to that of file descriptors: there is no atomic
+interface to allocate memory and store its address in the argument to a
+cleanup handler, or to release it and remove its address from that
+argument, without at least temporarily disabling asynchronous
+cancellation, which these functions do not do.
+
+This remark does not by itself cause a function to be regarded as
+generally AC-Unsafe.  However, cumulative effects of such leaks may be
+severe enough for some programs that disabling asynchronous cancellation
+for the duration of calls to such functions may be required.
+
+
+@item @code{unposix}
+@cindex unposix
+
+This remark indicates our safety documentation is known to differ from
+the requirements set by the POSIX standard.  For example, POSIX does not
+require a function to be Safe, but our implementation is Safe, or
+vice-versa.
+
+For the time being, the absence of this remark does not imply the safety
+properties we documented are identical to those mandated by POSIX for
+the corresponding functions.
+
+
+@end itemize
+
 
 @node Berkeley Unix, SVID, POSIX, Standards and Portability
 @subsection Berkeley Unix
diff --git a/manual/macros.texi b/manual/macros.texi
index daaf1c0..6955f32 100644
--- a/manual/macros.texi
+++ b/manual/macros.texi
@@ -47,4 +47,46 @@ GNU/Hurd systems
 GNU/Linux systems
 @end macro
 
+@c Document a function as thread safe.
+@macro mtsafe {comments}
+| MT-Safe \comments\
+|
+@end macro
+@c Document a function as thread unsafe.
+@macro mtunsafe {comments}
+| MT-Unsafe \comments\
+|
+@end macro
+@c Document a function as safe for use in asynchronous signal handlers.
+@macro assafe {comments}
+| AS-Safe \comments\
+|
+@end macro
+@c Document a function as unsafe for use in asynchronous signal
+@c handlers.  This distinguishes unmarked functions, for which this
+@c property has not been assessed, from those that have been analyzed.
+@macro asunsafe {comments}
+| AS-Unsafe \comments\
+|
+@end macro
+@c Document a function as safe for use when asynchronous cancellation is
+@c enabled.
+@macro acsafe {comments}
+| AC-Safe \comments\
+|
+@end macro
+@c Document a function as unsafe for use when asynchronous cancellation
+@c is enabled.  This distinguishes unmarked functions, for which this
+@c property has not been assessed, from those that have been analyzed.
+@macro acunsafe {comments}
+| AC-Unsafe \comments\
+|
+@end macro
+@c Format the thread and async safety properties of a function.
+@macro safety {notes}
+\notes\
+
+
+@end macro
+
 @end ifclear
diff --git a/manual/intro.texi b/manual/intro.texi
index 569f696..97712f2 100644
--- a/manual/intro.texi
+++ b/manual/intro.texi
@@ -159,6 +159,15 @@ Utilities standard} (POSIX.2) are also implemented in @theglibc{}.
 These include utilities for dealing with regular expressions and other
 pattern matching facilities (@pxref{Pattern Matching}).
 
+@menu
+* POSIX Safety Concepts::       Safety concepts from POSIX.
+* Unconditional Unsafety::      Features that make functions
+                                 unconditionally unsafe.
+* Avoidable Unsafety::          Features that make functions unsafe,
+                                 but that can be worked around.
+* Other Safety Remarks::        Additional safety features and remarks.
+@end menu
+
 @comment Roland sez:
 @comment The GNU C library as it stands conforms to 1003.2 draft 11, which
 @comment specifies:
@@ -172,13 +181,17 @@ pattern matching facilities (@pxref{Pattern Matching}).
 @comment <wordexp.h> (not yet implemented)
 @comment confstr
 
+@node POSIX Safety Concepts, Unconditional Unsafety, , POSIX
+@subsubsection POSIX Safety Concepts
+@cindex POSIX Safety Concepts
+
 The safety properties of @glibcadj{} functions, documented as MT-, AS-
 and AC- -Safe and -Unsafe are assessed according to the criteria set
-forth in the POSIX standard for Multi-Thread, Async-Signal and
-Async-Cancel safety.
+forth in the POSIX standard for Thread-, Async-Signal- and Async-Cancel-
+safety.
 
-Intuitive definition of these properties, that attempt to capture
-the meaning of the standard definitions, follow:
+Intuitive definitions of these properties, attempting to capture the
+meaning of the standard definitions, follow:
 
 @itemize @bullet
 
@@ -187,11 +200,37 @@ the meaning of the standard definitions, follow:
 MT-Safe functions are safe to call in the presence of other threads.  MT
 stands for Multi Thread.
 
+A function being MT-Safe does not imply any form of synchronization, nor
+that any combination of calls of MT-Safe functions would be regarded as
+MT-Safe.  For example, having a thread call two MT-Safe functions one
+right after the other does not guarantee behavior equivalent to atomic
+execution of a combination of both functions, since concurrent calls in
+other threads may cause behavior to diverge.
+
+In some cases, even expanding MT-Safe functions inline could cause
+combinations to become MT-Unsafe due to reordering that this could
+enable; this is never the case of @glibcadj{} functions defined in
+user-visible headers, because these are meant to be inlined, but it may
+be for functions that are exported by @glibcadj{} shared libraries;
+whole-program optimizations that might inline functions across library
+interfaces might expose this sort of problem, so performing inlining
+across the @glibcadj{} interface is not recommended, nor is the
+documented MT-Safety status guaranteed under such arrangements.
+
 @item
 @cindex AS-Safe
 AS-Safe functions are safe to call from asynchronous signal handlers.
 AS stands for Asynchronous Signal.
 
+Many functions that are AS-Safe may set @code{errno}, or modify the
+floating-point environment, because their doing so does not make them
+unsuitable for use in signal handlers.  However, programs could
+misbehave should asynchronous signal handlers modify this thread-local
+state, and the signal handling machinery cannot be counted on to
+preserve it.  Therefore, signal handlers that call functions that may
+set @code{errno} or modify the floating-point environment @emph{must}
+save their original values, and restore them before returning.
+
 @item
 @cindex AC-Safe
 AC-Safe functions are safe to call when asynchronous cancellation is
@@ -202,9 +241,8 @@ enabled.  AC stands for Asynchronous Cancellation.
 @cindex AS-Unsafe
 @cindex AC-Unsafe
 MT-Unsafe, AS-Unsafe, AC-Unsafe functions are not safe to call within
-the contexts described above: they may cause deviations from the
-specification in the behavior of the calls themselves, or of any other
-concurrent, ongoing or subsequent calls.
+the contexts described above.  Calling them within such contexts invokes
+undefined behavior.
 
 Functions not explicitly documented as Safe should be regarded as
 Unsafe.
@@ -213,7 +251,7 @@ Unsafe.
 
 By ``safe to call'', we mean that, as long as the program does not
 invoke undefined or unspecified behavior, the called functions will
-behave as documented, and they won't cause any other functions to
+behave as documented, and they will not cause any other functions to
 deviate from their documented behavior.
 
 Although we strive to abide by the standards, in some cases our
@@ -225,64 +263,180 @@ this manual is not to be regarded as a promise of future behavior: in
 future releases, functions that are documented as safe may become
 unsafe, and safety constraints may be removed or introduced.  We
 envision turning the results of the assessment into a set of promises as
-stable as our interfaces, but we're not there yet.
+stable as our interfaces, but we are not there yet.
+
+@node Unconditional Unsafety, Avoidable Unsafety, POSIX Safety Concepts, POSIX
+@subsubsection Unconditional Unsafety
+@cindex Unconditional Unsafety
 
-When a function is safe to call only under certain constraints, we will
-add keywords to the safety notes whose meanings are defined as follows:
+Functions that are unsafe to call in certain contexts are annotated with
+keywords that document their features that make them unsafe to call:
 
 @itemize @bullet
 
-@c glocale-revisit
-@item @code{glocale}
-@cindex glocale
+@item @code{staticbuf}
+@cindex staticbuf
 
-In threads that have not overridden the thread-local locale object by
-calling @code{uselocale}, calling functions annotated with
-@code{glocale} concurrently with @code{setlocale} may cause the
-functions to behave in ways that don't correspond to either the previous
-or the subsequent global locale.
+Functions annotated with @code{staticbuf} use internal objects in ways
+that may cause concurrent calls to interfere destructively.  In this
+case internal does not mean the objects are not exposed to callers, just
+that they are not supplied by callers (contrast with the @code{uunguard}
+and @code{xguargs} keywords).
 
-Although the @code{setlocale} function modifies the global locale object
-while holding a lock, @code{glocale}-annotated functions may access this
-global object multiple times, without any measures to ensure it doesn't
-change while it's in use.
+These functions are all MT-Unsafe and AS-Unsafe.  However, many of them
+offer reentrant variants for MT-Safe and, in some cases, AS-Safe use.
 
-Each of these unprotected uses will use either the previous or the
-subsequent locale information, so they won't cause crashes or access to
-uninitialized, unmapped or recycled memory.  However, since some cases
-use cached locale information while others access the effective locale
-object anew, concurrent changes to the global locale object may cause
-these functions to behave in ways that they could not behave should the
-execution of @code{setlocale} and of the so-annotated functions be
-atomic, or even should @code{setlocale} alone be atomic.
+In many of these cases, the static buffer is only used to hold a return
+value; in a few of these, such as @code{tmpnam}, the use of the internal
+buffer can be avoided by passing the buffer as an argument, which makes
+the call MT-Safe and AS-Safe.
 
-The @code{glocale} constraint indicates functions are only safe to call
-if the effective thread-local locale is not the global locale object
-(because it was overridden with @code{uselocale}).  Failing that,
-@code{setlocale} should not be called while these functions are active.
 
+@item @code{lockleak}
+@cindex lockleak
 
-@item @code{envromt}
-@cindex envromt
+Functions annotated with @code{lockleak} may leak locks if asynchronous
+thread cancellation interrupts their execution.
 
-Functions marked with @code{envromt} access the environment with
-@code{getenv} or similar, requiring the environment to be effectively
-read-only for MT-Safe operation.
+While the problem is similar to that of file descriptors, in that there
+is not any atomic interface to lock and take note of the need for
+unlocking in a cleanup, or to unlock and take note that there is no
+longer such a need, the problem posed by lock leaks is far more serious:
+when a file descriptor or a piece of memory is leaked, it becomes
+inaccessible and subsequent attempts to allocate a file descriptor or
+some memory will just use another resource.  However, once a lock is
+left taken, attempts to take that lock will block indefinitely.
+(Recursive locks will only block other threads, and read locks will only
+block writer threads, but the point still holds in general).
 
-Environment-modifying functions do not protect in any way against
-concurrent modifications or access, so calling @code{envromt}-marked
-functions concurrently with @code{setenv}, @code{putenv},
-@code{unsetenv} or direct modifications of the global environment data
-structures is ill-advised; external concurrency control must be
-introduced by callers of these environment-modifying and
-@code{envromt}-marked functions.
+For the reasons above, functions that leak locks are all AC-Unsafe.
 
-Functions that modify the environment are also marked with
-@code{envromt}, but they are not MT-Safe for the reasons above.  Since
-all environment-modifying functions are MT-Unsafe, functions that only
-access the environment are marked as MT-Safe when no other safety issue
-applies.
 
+@item @code{selfdeadlock}
+@cindex selfdeadlock
+
+Functions marked with @code{selfdeadlock} take a non-recursive lock to
+ensure MT-Safety while modifying data structures guarded by the lock.
+
+If such a function is called by a signal handler that interrupted
+another such function that took the lock, the result is a deadlock.
+
+Blocking asynchronous signal delivery while calling such functions is
+the only safe way to avoid a deadlock if any signal handler might need
+to call them.
+
+
+@item @code{asynconsist}
+@cindex asynconsist
+
+Functions marked with @code{asynconsist} take a recursive lock to ensure
+MT-Safety while accessing or modifying data structures guarded by the
+lock.
+
+If such a function is called by a signal handler that interrupted
+another such function that took the lock, both may misbehave for
+observing inconsistent (partially updated or cached) data structures.
+
+Blocking asynchronous signal delivery while calling such functions is
+the only safe way to avoid the misbehavior that may ensue if any signal
+handler might need to call them.
+
+
+@item @code{incansist}
+@cindex incansist
+
+Functions marked with @code{incansist} modify data structures in a
+non-atomic way.
+
+If such a function is asynchronously cancelled, it may leave the data
+structure in a partially updated, inconsistent state.  Subsequent uses
+of the data structure may misbehave.
+
+Disabling asynchronous cancellation while calling such functions is the
+only safe way to avoid the misbehavior if the thread is cancelled while
+the function is running.
+
+@c A special case, probably not worth documenting separately, involves
+@c reallocing, or even freeing pointers.  Any case involving free could
+@c be easily turned into an ac-safe memleak by resetting the pointer
+@c before releasing it; I don't think we have any case that calls for
+@c this sort of fixing.  Fixing the realloc cases would require a new
+@c interface: instead of @code{ptr=realloc(ptr,size)} we'd have to
+@c introduce @code{acsafe_realloc(&ptr,size)} that would modify ptr
+@c before releasing the old memory.  The ac-unsafe realloc could be
+@c implemented in terms of an internal interface with this semantics
+@c (say __acsafe_realloc), but since realloc can be overridden, the
+@c function we call to implement realloc should not be this internal
+@c interface, but another internal interface that calls __acsafe_realloc
+@c if realloc was not overridden, and calls the overridden realloc with
+@c async cancel disabled.  --lxoliva
+
+
+@item @code{asmalloc}
+@cindex asmalloc
+
+Functions marked with @code{asmalloc} perform memory allocation or
+deallocation with the @code{malloc}/@code{free} family of functions,
+thus implying all of the keywords of these functions.
+
+If heap management functions are interrupted by asynchronous signals,
+and the signal handlers attempt to perform memory allocation or
+deallocation of their own, they may encounter heap data structures in a
+partially updated state, and the interrupted calls may malfunction
+because of the changes made within the signal handler.
+
+
+@item @code{asi18n}
+@cindex asi18n
+
+Functions marked with @code{asi18n} call internationalization functions
+of the @code{gettext} family, thus implying all of the keywords
+of @code{gettext}.
+
+
+@item @code{shlimb}
+@cindex shlimb
+
+Functions marked with @code{shlimb} use the dynamic loader to bring in
+additional code modules.  This involves opening files, mapping them into
+memory, allocating additional memory, resolving symbols, applying
+relocations and more, all of this while holding internal dynamic loader
+locks.
+
+The locks are enough for these functions to be AS- and AC-Unsafe, but
+other issues may arise; the safety documentation of @code{dlopen}, when
+available, shall list all the keywords implied by this one.
+
+
+@item @code{uplugin}
+@cindex uplugin
+
+Functions annotated with @code{uplugin} may run code from plugins that
+may be external to @theglibc{}.  Such plug-in functions are assumed to
+be MT-Safe, AS-Unsafe and AC-Unsafe.
+
+Examples of such plugins are stack unwinding libraries and nss
+back-ends.
+
+
+@end itemize
+
+
+@node Avoidable Unsafety, Other Safety Remarks, Unconditional Unsafety, POSIX
+@subsubsection Avoidable Unsafety
+@cindex Avoidable Unsafety
+
+For some features that make functions unsafe to call in certain
+contexts, there are known ways to avoid the safety problem other than
+refraining from calling the function altogether.  The keywords that
+follow refer to such features, and each of their definitions indicate
+how the whole program needs to be constrained in order to remove the
+safety problem indicated by the keyword.  Only when all the reasons that
+make a function unsafe are observed and addressed by applying the
+documented constraints does the function become safe to call in a
+context.
+
+@itemize @bullet
 
 @item @code{oncesafe}
 @cindex oncesafe
@@ -309,34 +463,37 @@ related with @code{libc_once} do not arise.
 @item @code{1stcall}
 @cindex 1stcall
 
-Functions marked with @code{1stcall} perform thread-unsafe
-initialization when they are first called.
-
-In order to prevent this thread-unsafe initialization from rendering the
-functions unsafe to call in multi-threaded programs, such functions
-should be called at least once in single-threaded mode, i.e., before
-additional threads are started.
+Functions marked with @code{1stcall} perform MT-unsafe initialization
+when they are first called.  
 
-If @code{1stcall} is the only reason for a function to be marked as
-MT-Unsafe, and the function is first called in single-threaded mode,
-then it becomes safe to call after other threads are started.
+Calling such a function at least once in single-threaded mode removes
+this specific cause for the function to be regarded as MT-Unsafe.  If no
+other cause for that remains, the function can then be safely called
+after other threads are started.
 
 
 @item @code{uunguard}
 @cindex uunguard
 
 Functions marked with @code{uunguard} modify non-atomically arguments or
-global objects that other functions access without synchronization.  To
-ensure MT- and AS-Safe behavior, callers should refrain from calling
-so-marked functions concurrently with readers of those objects.  A
+global objects that other functions access without synchronization.  A
 consequence of regarding modifiers of these objects as unsafe is that
 the covered objects can be regarded as constant (subject to the
 observation of safety constraints), so that all readers can be
 considered safe in this regard.
 
+In order to avoid the safety issues posed by these unguarded accesses,
+callers must guard calls to @emph{all} readers and writers of the
+affected objects with something equivalent to a @code{rwlock}, i.e.,
+writers must get exclusive access, while multiple concurrent readers may
+be allowed.
+
 Unguarded users of the global locale object modified by @code{setlocale}
 are marked with @code{glocale}.
 
+Unguarded users of the global environment are marked with
+@code{envromt}.
+
 Unguarded users of the @code{printf} extension objects modified by
 @code{register_printf_function} are the entire family of printf
 functions.
@@ -435,58 +592,73 @@ In a multi-threaded program, there is a risk that the time-out signal
 will be delivered to a different thread, thus failing to interrupt the
 intended thread.
 
-Keeping @code{SIGALARM} blocked on all threads, and refraining from
-calling concurrenly functions that may set up such timers, is the only
-way to avoid the safety issue at hand.
+Keeping @code{SIGALRM} blocked on all threads, and refraining from
+concurrently calling functions that may set up such timers, is the only
+way to avoid this safety issue.
 
 
 @end itemize
 
 
-Additional safety issues that cannot be worked around by constraining
-the program (other than by refraining from calling the affected
-functions) are also documented with keywords, whose meaning is defined
-as follows:
+@node Other Safety Remarks, , Avoidable Unsafety, POSIX
+@subsubsection Other Safety Remarks
+@cindex Other Safety Remarks
 
-@itemize @bullet
+Additional keywords may be attached to functions, indicating features
+that do not make a function unsafe to call, but that may need to be
+taken into account in certain classes of programs:
 
-@item @code{staticbuf}
-@cindex staticbuf
+@itemize @bullet
 
-Functions annotated with @code{staticbuf} use internal objects in ways
-that may cause concurrent calls to interfere destructively.  Internal,
-here, does not mean the objects are not exposed to callers, just that
-they are not supplied by callers (contrast with the @code{uunguard} and
-@code{xguargs} keywords).
+@item @code{glocale}
+@cindex glocale
 
-These functions are all MT-Unsafe and AS-Unsafe.  However, many of them
-offer reentrant variants for MT-Safe and, in some cases, AS-Safe use.
+In threads that have not overridden the thread-local locale object by
+calling @code{uselocale}, calling functions annotated with
+@code{glocale} concurrently with @code{setlocale} may cause the
+functions to behave in ways that do not correspond to either the
+previous or the subsequent global locale.
 
-In many of these cases, the static buffer is only used to hold a return
-value; in a few of these, such as @code{tmpnam}, the use of the internal
-buffer can be avoided by passing the buffer as an argument, which makes
-the call MT-Safe and AS-Safe.
+Although the @code{setlocale} function modifies the global locale object
+while holding a lock, @code{glocale}-annotated functions may access this
+global object multiple times, without any measures to ensure it does not
+change while it is in use.
 
+Each of these unprotected uses will use either the previous or the
+subsequent locale information, so they will not cause crashes or access
+to uninitialized, unmapped or recycled memory.  However, sometimes
+cached local information is used whereas in other cases, the locale
+object is accessed anew; thus, concurrent changes to the global locale
+object may cause these functions to behave in unexpected ways (i.e.,
+behavior that is not possible if @code{setlocale} and the so-annotated
+functions would have been executed in some sequential order).
 
-@item @code{asi18n}
-@cindex asi18n
+The @code{glocale} constraint indicates functions are only safe to call
+if the effective thread-local locale is not the global locale object
+(because it was overridden with @code{uselocale}).  Failing that,
+@code{setlocale} should not be called while these functions are active.
 
-Functions marked with @code{asi18n} use internationalization functions
-(@code{gettext}), which brings in a number of dependencies and issues
-yet to be documented.
 
+@item @code{envromt}
+@cindex envromt
 
-@item @code{shlimb}
-@cindex shlimb
+Functions marked with @code{envromt} access the environment with
+@code{getenv} or similar, requiring the environment to be effectively
+read-only for MT-Safe operation.
 
-Functions marked with @code{shlimb} use the dynamic loader to bring in
-additional code modules.  This involves opening files, mapping them into
-memory, allocating additional memory, resolving symbols, applying
-relocations and more, all of this while holding the dynamic loader
-lock.
+Environment-modifying functions do not protect in any way against
+concurrent modifications or access.  Calling @code{envromt}-marked
+functions concurrently with @code{setenv}, @code{putenv},
+@code{unsetenv} or direct modifications of the global environment data
+structures is ill-advised; external concurrency control must be
+introduced by callers of these environment-modifying and
+@code{envromt}-marked functions.
 
-The non-recursive lock itself is enough for the function to be AS- and
-AC-Unsafe, but many other issues may arise.
+Functions that modify the environment are also marked with
+@code{envromt}, but they are not MT-Safe for the reasons above.  Since
+all environment-modifying functions are MT-Unsafe, functions that only
+access the environment are marked as MT-Safe when no other safety issue
+applies.
 
 
 @item @code{fdleak}
@@ -503,12 +675,12 @@ release it cannot be performed as a single atomic operation, just like
 releasing it and taking it out of the data structure normally
 responsible for releasing it cannot be performed atomically, always
 leaving a window in which the descriptor cannot be released because it
-wasn't stored in the cleanup handler argument yet, or in which it was
+was not stored in the cleanup handler argument yet, or in which it was
 already taken out of it before releasing it in the normal flow (we
-cannot keep it there because, in case of cancellation, we wouldn't be
+cannot keep it there because, in case of cancellation, we would not be
 able to tell whether it was already released, and the same number could
 have been already assigned to another descriptor by another thread, so
-we couldn't just release it again).
+we could not just release it again).
 
 Such leaks could be internally avoided, with some performance penalty,
 by temporarily disabling asynchronous thread cancellation.  However,
@@ -516,10 +688,10 @@ since callers of allocation or deallocation functions would have to do
 this themselves, to avoid the same sort of leak in their own layer, it
 makes more sense for the library to assume they are taking care of it
 than to impose a performance penalty that is redundant when the problem
-is solved in upper layers, and insufficient when it isn't.
+is solved in upper layers, and insufficient when it is not.
 
 This remark by itself does not cause a function to be regarded as
-AC-Unsafe.  However, cummulative effects of such leaks may pose a
+AC-Unsafe.  However, cumulative effects of such leaks may pose a
 problem for some programs.  If this is the case, suspending asynchronous
 cancellation for the duration of calls to such functions is recommended.
 
@@ -537,140 +709,11 @@ argument, without at least temporarily disabling asynchronous
 cancellation, which these functions do not do.
 
 This remark does not by itself cause a function to be regarded as
-generally AC-Unsafe.  However, cummulative effects of such leaks may be
+generally AC-Unsafe.  However, cumulative effects of such leaks may be
 severe enough for some programs that disabling asynchronous cancellation
 for the duration of calls to such functions may be required.
 
 
-@item @code{lockleak}
-@cindex lockleak
-
-Functions annotated with @code{lockleak} may leak locks if asynchronous
-thread cancellation interrupts their execution.
-
-While the problem is similar to that of file descriptors, in that there
-is not any atomic interface to lock and take note of the need for
-unlocking in a cleanup, or to unlock and take note that there is no
-longer such a need, the problem posed by lock leaks is far more serious:
-when a file descriptor or a piece of memory is leaked, it becomes
-inaccessible and subsequent attempts to allocate a file descriptor or
-some memory will just use another resource.  However, once a lock is
-left taken, attempts to take that lock will block indefinitely.
-(Recursive locks will only block other threads, and read locks will only
-block writer threads, but the point still holds in general).
-
-For the reasons above, functions that leak locks are all AC-Unsafe.
-
-
-@item @code{selfdeadlock}
-@cindex selfdeadlock
-
-Functions marked with @code{selfdeadlock} take a non-recursive lock to
-ensure MT-Safety while modifying data structures guarded by the lock.
-
-If such a function is called by a signal handler that interrupted
-another such function that took the lock, the result is a deadlock.
-
-Blocking asynchronous signal delivery while calling such functions is
-the only safe way to avoid a deadlock if any signal handler might need
-to call them.
-
-
-@item @code{asynconsist}
-@cindex asynconsist
-
-Functions marked with @code{asynconsist} take a recursive lock to ensure
-MT-Safety while accessing or modifying data structures guarded by the
-lock.
-
-If such a function is called by a signal handler that interrupted
-another such function that took the lock, both may misbehave for
-observing inconsistent (partially updated or cached) data structures.
-
-Blocking asynchronous signal delivery while calling such functions is
-the only safe way to avoid the misbehavior that may ensue if any signal
-handler might need to call them.
-
-
-@item @code{asmalloc}
-@cindex asmalloc
-
-This is a sub-case of @code{asynconsist}.  Functions marked with
-@code{asmalloc} perform memory allocation or deallocation with the
-@code{malloc}/@code{free} family of functions.
-
-If heap management functions are interrupted by asynchronous signals,
-and the signal handlers attempt to perform memory allocation or
-deallocation of their own, they may encounter heap data structures in a
-partially updated state, and the interrupted calls may malfunction
-because of the changes made within the signal handler.
-
-The @code{asmalloc} mark implies @code{selfdeadlock} (AS-unsafe) and
-@code{lockleak} (AC-Unsafe).
-
-
-@item @code{incansist}
-@cindex incansist
-
-Functions marked with @code{incansist} modify data structures in a
-non-atomic way.
-
-If such a function is asynchronously canceled, it may leave the data
-structure in a partially updated, inconsistent state.  Subsequent uses
-of the data structure may misbehave.
-
-Disabling asynchronous cancelation while calling such functions is the
-only safe way to avoid the misbehavior that may ensure if the thread is
-canceled while the function is running.
-
-@c A special case, probably not worth documenting separately, involves
-@c reallocing, or even freeing pointers.  Any case involving free could
-@c be easily turned into an ac-safe memleak by resetting the pointer
-@c before releasing it; I don't think we have any case that calls for
-@c this sort of fixing.  Fixing the realloc cases would require a new
-@c interface: instead of @code{ptr=realloc(ptr,size)} we'd have to
-@c introduce @code{acsafe_realloc(&ptr,size)} that would modify ptr
-@c before releasing the old memory.  The ac-unsafe realloc could be
-@c implemented in terms of an internal interface with this semantics
-@c (say __acsafe_realloc), but since realloc can be overridden, the
-@c function we call to implement realloc should not be this internal
-@c interface, but another internal interface that calls __acsafe_realloc
-@c if realloc was not overridden, and calls the overridden realloc with
-@c async cancel disabled.  --lxoliva
-
-
-@item @code{uplugin}
-@cindex uplugin
-
-Functions annotated with @code{uplugin} may run code from plugins that
-may be external to @theglibc{}.  Such plug-in functions are assumed to
-be MT-Safe, AS-Unsafe and AC-Unsafe.
-
-Examples of such plugins are stack unwinding libraries and nss
-back-ends.
-
-
-@item @code{simfpu}
-@cindex simfpu
-
-Functions annotated with @code{simfpu} may misbehave on powerpc ports in
-which the floating-point unit is disabled and floating point simulation
-is used instead.  On such platforms, @theglibc{} uses global variables
-to hold floating-point exceptions, rounding modes and disabled
-exceptions, rather than thread-local state.  This is a @glibcadj{} bug.
-
-Furthermore, even if this bug is fixed, the emulation of floating-point
-control and status registers will not go as far as saving and restoring
-these emulated registers across asynchronous signal handlers.  Indeed,
-although most platforms preserve floating-point context as part of the
-thread context, preserving control and status words is not mandatory:
-standards recommend that programs that modify them within signal
-handlers restore them to the original state before returning.
-
-This note does not cause functions to be marked as MT-Unsafe, even
-though, on the affected platform, they are MT-Unsafe indeed.
-
-
 @item @code{unposix}
 @cindex unposix
 
@@ -683,6 +726,7 @@ For the time being, the absence of this remark does not imply the safety
 properties we documented are identical to those mandated by POSIX for
 the corresponding functions.
 
+
 @end itemize
 
 
diff --git a/manual/intro.texi b/manual/intro.texi
index c87f190..97712f2 100644
--- a/manual/intro.texi
+++ b/manual/intro.texi
@@ -159,6 +159,15 @@ Utilities standard} (POSIX.2) are also implemented in @theglibc{}.
 These include utilities for dealing with regular expressions and other
 pattern matching facilities (@pxref{Pattern Matching}).
 
+@menu
+* POSIX Safety Concepts::       Safety concepts from POSIX.
+* Unconditional Unsafety::      Features that make functions
+                                 unconditionally unsafe.
+* Avoidable Unsafety::          Features that make functions unsafe,
+                                 but that can be worked around.
+* Other Safety Remarks::        Additional safety features and remarks.
+@end menu
+
 @comment Roland sez:
 @comment The GNU C library as it stands conforms to 1003.2 draft 11, which
 @comment specifies:
@@ -172,6 +181,10 @@ pattern matching facilities (@pxref{Pattern Matching}).
 @comment <wordexp.h> (not yet implemented)
 @comment confstr
 
+@node POSIX Safety Concepts, Unconditional Unsafety, , POSIX
+@subsubsection POSIX Safety Concepts
+@cindex POSIX Safety Concepts
+
 The safety properties of @glibcadj{} functions, documented as MT-, AS-
 and AC- -Safe and -Unsafe are assessed according to the criteria set
 forth in the POSIX standard for Thread-, Async-Signal- and Async-Cancel-
@@ -187,11 +200,37 @@ meaning of the standard definitions, follow:
 MT-Safe functions are safe to call in the presence of other threads.  MT
 stands for Multi Thread.
 
+A function being MT-Safe does not imply any form of synchronization, nor
+that any combination of calls of MT-Safe functions would be regarded as
+MT-Safe.  For example, having a thread call two MT-Safe functions one
+right after the other does not guarantee behavior equivalent to atomic
+execution of a combination of both functions, since concurrent calls in
+other threads may cause behavior to diverge.
+
+In some cases, even expanding MT-Safe functions inline could cause
+combinations to become MT-Unsafe due to reordering that this could
+enable; this is never the case of @glibcadj{} functions defined in
+user-visible headers, because these are meant to be inlined, but it may
+be for functions that are exported by @glibcadj{} shared libraries;
+whole-program optimizations that might inline functions across library
+interfaces might expose this sort of problem, so performing inlining
+across the @glibcadj{} interface is not recommended, nor is the
+documented MT-Safety status guaranteed under such arrangements.
+
 @item
 @cindex AS-Safe
 AS-Safe functions are safe to call from asynchronous signal handlers.
 AS stands for Asynchronous Signal.
 
+Many functions that are AS-Safe may set @code{errno}, or modify the
+floating-point environment, because their doing so does not make them
+unsuitable for use in signal handlers.  However, programs could
+misbehave should asynchronous signal handlers modify this thread-local
+state, and the signal handling machinery cannot be counted on to
+preserve it.  Therefore, signal handlers that call functions that may
+set @code{errno} or modify the floating-point environment @emph{must}
+save their original values, and restore them before returning.
+
 @item
 @cindex AC-Safe
 AC-Safe functions are safe to call when asynchronous cancellation is
@@ -202,9 +241,8 @@ enabled.  AC stands for Asynchronous Cancellation.
 @cindex AS-Unsafe
 @cindex AC-Unsafe
 MT-Unsafe, AS-Unsafe, AC-Unsafe functions are not safe to call within
-the contexts described above: they may cause deviations from the
-specification in the behavior of the calls themselves, or of any other
-concurrent, ongoing or subsequent calls.
+the contexts described above.  Calling them within such contexts invokes
+undefined behavior.
 
 Functions not explicitly documented as Safe should be regarded as
 Unsafe.
@@ -227,62 +265,179 @@ unsafe, and safety constraints may be removed or introduced.  We
 envision turning the results of the assessment into a set of promises as
 stable as our interfaces, but we are not there yet.
 
-When a function is safe to call only under certain constraints, we will
-add keywords to the safety notes whose meanings are defined as follows:
+@node Unconditional Unsafety, Avoidable Unsafety, POSIX Safety Concepts, POSIX
+@subsubsection Unconditional Unsafety
+@cindex Unconditional Unsafety
+
+Functions that are unsafe to call in certain contexts are annotated with
+keywords that document their features that make them unsafe to call:
 
 @itemize @bullet
 
-@item @code{glocale}
-@cindex glocale
+@item @code{staticbuf}
+@cindex staticbuf
 
-In threads that have not overridden the thread-local locale object by
-calling @code{uselocale}, calling functions annotated with
-@code{glocale} concurrently with @code{setlocale} may cause the
-functions to behave in ways that do not correspond to either the
-previous or the subsequent global locale.
+Functions annotated with @code{staticbuf} use internal objects in ways
+that may cause concurrent calls to interfere destructively.  In this
+case internal does not mean the objects are not exposed to callers, just
+that they are not supplied by callers (contrast with the @code{uunguard}
+and @code{xguargs} keywords).
 
-Although the @code{setlocale} function modifies the global locale object
-while holding a lock, @code{glocale}-annotated functions may access this
-global object multiple times, without any measures to ensure it does not
-change while it is in use.
+These functions are all MT-Unsafe and AS-Unsafe.  However, many of them
+offer reentrant variants for MT-Safe and, in some cases, AS-Safe use.
 
-Each of these unprotected uses will use either the previous or the
-subsequent locale information, so they will not cause crashes or access
-to uninitialized, unmapped or recycled memory.  However, since some
-cases use cached locale information while others access the effective
-locale object anew, concurrent changes to the global locale object may
-cause these functions to behave in ways that they could not behave
-should the execution of @code{setlocale} and of the so-annotated
-functions be atomic, or even should @code{setlocale} alone be atomic.
+In many of these cases, the static buffer is only used to hold a return
+value; in a few of these, such as @code{tmpnam}, the use of the internal
+buffer can be avoided by passing the buffer as an argument, which makes
+the call MT-Safe and AS-Safe.
 
-The @code{glocale} constraint indicates functions are only safe to call
-if the effective thread-local locale is not the global locale object
-(because it was overridden with @code{uselocale}).  Failing that,
-@code{setlocale} should not be called while these functions are active.
 
+@item @code{lockleak}
+@cindex lockleak
 
-@item @code{envromt}
-@cindex envromt
+Functions annotated with @code{lockleak} may leak locks if asynchronous
+thread cancellation interrupts their execution.
 
-Functions marked with @code{envromt} access the environment with
-@code{getenv} or similar, requiring the environment to be effectively
-read-only for MT-Safe operation.
+While the problem is similar to that of file descriptors, in that there
+is not any atomic interface to lock and take note of the need for
+unlocking in a cleanup, or to unlock and take note that there is no
+longer such a need, the problem posed by lock leaks is far more serious:
+when a file descriptor or a piece of memory is leaked, it becomes
+inaccessible and subsequent attempts to allocate a file descriptor or
+some memory will just use another resource.  However, once a lock is
+left taken, attempts to take that lock will block indefinitely.
+(Recursive locks will only block other threads, and read locks will only
+block writer threads, but the point still holds in general).
 
-Environment-modifying functions do not protect in any way against
-concurrent modifications or access.  Calling @code{envromt}-marked
-functions concurrently with @code{setenv}, @code{putenv},
-@code{unsetenv} or direct modifications of the global environment data
-structures is ill-advised; external concurrency control must be
-introduced by callers of these environment-modifying and
-@code{envromt}-marked functions.
+For the reasons above, functions that leak locks are all AC-Unsafe.
 
-Functions that modify the environment are also marked with
-@code{envromt}, but they are not MT-Safe for the reasons above.  Since
-all environment-modifying functions are MT-Unsafe, functions that only
-access the environment are marked as MT-Safe when no other safety issue
-applies.
+
+@item @code{selfdeadlock}
+@cindex selfdeadlock
+
+Functions marked with @code{selfdeadlock} take a non-recursive lock to
+ensure MT-Safety while modifying data structures guarded by the lock.
+
+If such a function is called by a signal handler that interrupted
+another such function that took the lock, the result is a deadlock.
+
+Blocking asynchronous signal delivery while calling such functions is
+the only safe way to avoid a deadlock if any signal handler might need
+to call them.
+
+
+@item @code{asynconsist}
+@cindex asynconsist
+
+Functions marked with @code{asynconsist} take a recursive lock to ensure
+MT-Safety while accessing or modifying data structures guarded by the
+lock.
+
+If such a function is called by a signal handler that interrupted
+another such function that took the lock, both may misbehave for
+observing inconsistent (partially updated or cached) data structures.
+
+Blocking asynchronous signal delivery while calling such functions is
+the only safe way to avoid the misbehavior that may ensue if any signal
+handler might need to call them.
+
+
+@item @code{incansist}
+@cindex incansist
+
+Functions marked with @code{incansist} modify data structures in a
+non-atomic way.
+
+If such a function is asynchronously cancelled, it may leave the data
+structure in a partially updated, inconsistent state.  Subsequent uses
+of the data structure may misbehave.
+
+Disabling asynchronous cancellation while calling such functions is the
+only safe way to avoid the misbehavior if the thread is cancelled while
+the function is running.
+
+@c A special case, probably not worth documenting separately, involves
+@c reallocing, or even freeing pointers.  Any case involving free could
+@c be easily turned into an ac-safe memleak by resetting the pointer
+@c before releasing it; I don't think we have any case that calls for
+@c this sort of fixing.  Fixing the realloc cases would require a new
+@c interface: instead of @code{ptr=realloc(ptr,size)} we'd have to
+@c introduce @code{acsafe_realloc(&ptr,size)} that would modify ptr
+@c before releasing the old memory.  The ac-unsafe realloc could be
+@c implemented in terms of an internal interface with this semantics
+@c (say __acsafe_realloc), but since realloc can be overridden, the
+@c function we call to implement realloc should not be this internal
+@c interface, but another internal interface that calls __acsafe_realloc
+@c if realloc was not overridden, and calls the overridden realloc with
+@c async cancel disabled.  --lxoliva
+
+
+@item @code{asmalloc}
+@cindex asmalloc
+
+Functions marked with @code{asmalloc} perform memory allocation or
+deallocation with the @code{malloc}/@code{free} family of functions,
+thus implying all of the keywords of these functions.
+
+If heap management functions are interrupted by asynchronous signals,
+and the signal handlers attempt to perform memory allocation or
+deallocation of their own, they may encounter heap data structures in a
+partially updated state, and the interrupted calls may malfunction
+because of the changes made within the signal handler.
+
+
+@item @code{asi18n}
+@cindex asi18n
+
+Functions marked with @code{asi18n} call internationalization functions
+of the @code{gettext} family, thus implying all of the keywords
+of @code{gettext}.
+
+
+@item @code{shlimb}
+@cindex shlimb
+
+Functions marked with @code{shlimb} use the dynamic loader to bring in
+additional code modules.  This involves opening files, mapping them into
+memory, allocating additional memory, resolving symbols, applying
+relocations and more, all of this while holding internal dynamic loader
+locks.
+
+The locks are enough for these functions to be AS- and AC-Unsafe, but
+other issues may arise; the safety documentation of @code{dlopen}, when
+available, shall list all the keywords implied by this one.
+
+
+@item @code{uplugin}
+@cindex uplugin
+
+Functions annotated with @code{uplugin} may run code from plugins that
+may be external to @theglibc{}.  Such plug-in functions are assumed to
+be MT-Safe, AS-Unsafe and AC-Unsafe.
+
+Examples of such plugins are stack unwinding libraries and nss
+back-ends.
+
+
+@end itemize
 
 
+@node Avoidable Unsafety, Other Safety Remarks, Unconditional Unsafety, POSIX
+@subsubsection Avoidable Unsafety
+@cindex Avoidable Unsafety
+
+For some features that make functions unsafe to call in certain
+contexts, there are known ways to avoid the safety problem other than
+refraining from calling the function altogether.  The keywords that
+follow refer to such features, and each of their definitions indicate
+how the whole program needs to be constrained in order to remove the
+safety problem indicated by the keyword.  Only when all the reasons that
+make a function unsafe are observed and addressed by applying the
+documented constraints does the function become safe to call in a
+context.
+
+@itemize @bullet
+
 @item @code{oncesafe}
 @cindex oncesafe
 
@@ -321,17 +476,24 @@ after other threads are started.
 @cindex uunguard
 
 Functions marked with @code{uunguard} modify non-atomically arguments or
-global objects that other functions access without synchronization.  To
-ensure MT- and AS-Safe behavior, callers should refrain from calling
-so-marked functions concurrently with readers of those objects.  A
+global objects that other functions access without synchronization.  A
 consequence of regarding modifiers of these objects as unsafe is that
 the covered objects can be regarded as constant (subject to the
 observation of safety constraints), so that all readers can be
 considered safe in this regard.
 
+In order to avoid the safety issues posed by these unguarded accesses,
+callers must guard calls to @emph{all} readers and writers of the
+affected objects with something equivalent to a @code{rwlock}, i.e.,
+writers must get exclusive access, while multiple concurrent readers may
+be allowed.
+
 Unguarded users of the global locale object modified by @code{setlocale}
 are marked with @code{glocale}.
 
+Unguarded users of the global environment are marked with
+@code{envromt}.
+
 Unguarded users of the @code{printf} extension objects modified by
 @code{register_printf_function} are the entire family of printf
 functions.
@@ -438,50 +600,65 @@ way to avoid this safety issue.
 @end itemize
 
 
-Additional safety issues that cannot be worked around by constraining
-the program (other than by refraining from calling the affected
-functions) are also documented with keywords, whose meanings are defined
-as follows:
+@node Other Safety Remarks, , Avoidable Unsafety, POSIX
+@subsubsection Other Safety Remarks
+@cindex Other Safety Remarks
 
-@itemize @bullet
+Additional keywords may be attached to functions, indicating features
+that do not make a function unsafe to call, but that may need to be
+taken into account in certain classes of programs:
 
-@item @code{staticbuf}
-@cindex staticbuf
+@itemize @bullet
 
-Functions annotated with @code{staticbuf} use internal objects in ways
-that may cause concurrent calls to interfere destructively.  In this
-case internal does not mean the objects are not exposed to callers, just
-that they are not supplied by callers (contrast with the @code{uunguard}
-and @code{xguargs} keywords).
+@item @code{glocale}
+@cindex glocale
 
-These functions are all MT-Unsafe and AS-Unsafe.  However, many of them
-offer reentrant variants for MT-Safe and, in some cases, AS-Safe use.
+In threads that have not overridden the thread-local locale object by
+calling @code{uselocale}, calling functions annotated with
+@code{glocale} concurrently with @code{setlocale} may cause the
+functions to behave in ways that do not correspond to either the
+previous or the subsequent global locale.
 
-In many of these cases, the static buffer is only used to hold a return
-value; in a few of these, such as @code{tmpnam}, the use of the internal
-buffer can be avoided by passing the buffer as an argument, which makes
-the call MT-Safe and AS-Safe.
+Although the @code{setlocale} function modifies the global locale object
+while holding a lock, @code{glocale}-annotated functions may access this
+global object multiple times, without any measures to ensure it does not
+change while it is in use.
 
+Each of these unprotected uses will use either the previous or the
+subsequent locale information, so they will not cause crashes or access
+to uninitialized, unmapped or recycled memory.  However, sometimes
+cached local information is used whereas in other cases, the locale
+object is accessed anew; thus, concurrent changes to the global locale
+object may cause these functions to behave in unexpected ways (i.e.,
+behavior that is not possible if @code{setlocale} and the so-annotated
+functions would have been executed in some sequential order).
 
-@item @code{asi18n}
-@cindex asi18n
+The @code{glocale} constraint indicates functions are only safe to call
+if the effective thread-local locale is not the global locale object
+(because it was overridden with @code{uselocale}).  Failing that,
+@code{setlocale} should not be called while these functions are active.
 
-Functions marked with @code{asi18n} use internationalization functions
-(@code{gettext}), which brings in a number of dependencies and issues
-yet to be documented.
 
+@item @code{envromt}
+@cindex envromt
 
-@item @code{shlimb}
-@cindex shlimb
+Functions marked with @code{envromt} access the environment with
+@code{getenv} or similar, requiring the environment to be effectively
+read-only for MT-Safe operation.
 
-Functions marked with @code{shlimb} use the dynamic loader to bring in
-additional code modules.  This involves opening files, mapping them into
-memory, allocating additional memory, resolving symbols, applying
-relocations and more, all of this while holding internal dynamic loader
-locks.
+Environment-modifying functions do not protect in any way against
+concurrent modifications or access.  Calling @code{envromt}-marked
+functions concurrently with @code{setenv}, @code{putenv},
+@code{unsetenv} or direct modifications of the global environment data
+structures is ill-advised; external concurrency control must be
+introduced by callers of these environment-modifying and
+@code{envromt}-marked functions.
 
-The locks are enough for these functions to be AS- and AC-Unsafe, but
-other issues may arise.
+Functions that modify the environment are also marked with
+@code{envromt}, but they are not MT-Safe for the reasons above.  Since
+all environment-modifying functions are MT-Unsafe, functions that only
+access the environment are marked as MT-Safe when no other safety issue
+applies.
 
 
 @item @code{fdleak}
@@ -537,114 +714,6 @@ severe enough for some programs that disabling asynchronous cancellation
 for the duration of calls to such functions may be required.
 
 
-@item @code{lockleak}
-@cindex lockleak
-
-Functions annotated with @code{lockleak} may leak locks if asynchronous
-thread cancellation interrupts their execution.
-
-While the problem is similar to that of file descriptors, in that there
-is not any atomic interface to lock and take note of the need for
-unlocking in a cleanup, or to unlock and take note that there is no
-longer such a need, the problem posed by lock leaks is far more serious:
-when a file descriptor or a piece of memory is leaked, it becomes
-inaccessible and subsequent attempts to allocate a file descriptor or
-some memory will just use another resource.  However, once a lock is
-left taken, attempts to take that lock will block indefinitely.
-(Recursive locks will only block other threads, and read locks will only
-block writer threads, but the point still holds in general).
-
-For the reasons above, functions that leak locks are all AC-Unsafe.
-
-
-@item @code{selfdeadlock}
-@cindex selfdeadlock
-
-Functions marked with @code{selfdeadlock} take a non-recursive lock to
-ensure MT-Safety while modifying data structures guarded by the lock.
-
-If such a function is called by a signal handler that interrupted
-another such function that took the lock, the result is a deadlock.
-
-Blocking asynchronous signal delivery while calling such functions is
-the only safe way to avoid a deadlock if any signal handler might need
-to call them.
-
-
-@item @code{asynconsist}
-@cindex asynconsist
-
-Functions marked with @code{asynconsist} take a recursive lock to ensure
-MT-Safety while accessing or modifying data structures guarded by the
-lock.
-
-If such a function is called by a signal handler that interrupted
-another such function that took the lock, both may misbehave for
-observing inconsistent (partially updated or cached) data structures.
-
-Blocking asynchronous signal delivery while calling such functions is
-the only safe way to avoid the misbehavior that may ensue if any signal
-handler might need to call them.
-
-
-@item @code{asmalloc}
-@cindex asmalloc
-
-This is a sub-case of @code{asynconsist}.  Functions marked with
-@code{asmalloc} perform memory allocation or deallocation with the
-@code{malloc}/@code{free} family of functions.
-
-If heap management functions are interrupted by asynchronous signals,
-and the signal handlers attempt to perform memory allocation or
-deallocation of their own, they may encounter heap data structures in a
-partially updated state, and the interrupted calls may malfunction
-because of the changes made within the signal handler.
-
-The @code{asmalloc} mark implies @code{selfdeadlock} (AS-unsafe) and
-@code{lockleak} (AC-Unsafe).
-
-
-@item @code{incansist}
-@cindex incansist
-
-Functions marked with @code{incansist} modify data structures in a
-non-atomic way.
-
-If such a function is asynchronously cancelled, it may leave the data
-structure in a partially updated, inconsistent state.  Subsequent uses
-of the data structure may misbehave.
-
-Disabling asynchronous cancellation while calling such functions is the
-only safe way to avoid the misbehavior if the thread is cancelled while
-the function is running.
-
-@c A special case, probably not worth documenting separately, involves
-@c reallocing, or even freeing pointers.  Any case involving free could
-@c be easily turned into an ac-safe memleak by resetting the pointer
-@c before releasing it; I don't think we have any case that calls for
-@c this sort of fixing.  Fixing the realloc cases would require a new
-@c interface: instead of @code{ptr=realloc(ptr,size)} we'd have to
-@c introduce @code{acsafe_realloc(&ptr,size)} that would modify ptr
-@c before releasing the old memory.  The ac-unsafe realloc could be
-@c implemented in terms of an internal interface with this semantics
-@c (say __acsafe_realloc), but since realloc can be overridden, the
-@c function we call to implement realloc should not be this internal
-@c interface, but another internal interface that calls __acsafe_realloc
-@c if realloc was not overridden, and calls the overridden realloc with
-@c async cancel disabled.  --lxoliva
-
-
-@item @code{uplugin}
-@cindex uplugin
-
-Functions annotated with @code{uplugin} may run code from plugins that
-may be external to @theglibc{}.  Such plug-in functions are assumed to
-be MT-Safe, AS-Unsafe and AC-Unsafe.
-
-Examples of such plugins are stack unwinding libraries and nss
-back-ends.
-
-
 @item @code{unposix}
 @cindex unposix
 
@@ -657,6 +726,7 @@ For the time being, the absence of this remark does not imply the safety
 properties we documented are identical to those mandated by POSIX for
 the corresponding functions.
 
+
 @end itemize
 
 
-- 
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]