attributes — POSIX safety concepts
| ![[Note]](../stylesheet/note.png) | Note | 
|---|---|
| the text of this man page is based on the material taken from the "POSIX Safety Concepts" section of the GNU C Library manual. Further details on the topics described here can be found in that manual. | 
Various function manual pages include a section ATTRIBUTES that describes the safety of calling the function in various contexts. This section annotates functions with the following safety markings:
MT-SafeMT-Safe or
            Thread-Safe functions are safe to call in the presence
            of other threads. MT, in MT-Safe, stands for Multi
            Thread.
Being MT-Safe does not imply a function is atomic, nor that it uses any of the memory synchronization mechanisms POSIX exposes to users. It is even possible that calling MT-Safe functions in sequence does not yield an MT-Safe combination. 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 interfere in a destructive way.
Whole-program optimizations that could inline functions across library interfaces may expose unsafe reordering, and so performing inlining across the GNU C Library interface is not recommended. The documented MT-Safety status is not guaranteed under whole-program optimization. However, functions defined in user-visible headers are designed to be safe for inlining.
MT-UnsafeMT-Unsafe
            functions are not safe to call in a multithreaded
            programs.
Other keywords that appear in safety notes are defined in subsequent sections.
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 indicates 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.
initFunctions marked with init as an MT-Unsafe
              feature 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.
raceFunctions annotated with race as an MT-Safety
              issue operate on objects in ways that may cause data
              races or similar forms of destructive interference
              out of concurrent execution. In some cases, the
              objects are passed to the functions by users; in
              others, they are used by the functions to return
              values to users; in others, they are not even exposed
              to users.
constFunctions marked with const as an MT-Safety
              issue non-atomically modify internal objects that are
              better regarded as constant, because a substantial
              portion of the GNU C Library accesses them without
              synchronization. Unlike race, which causes
              both readers and writers of internal objects to be
              regarded as MT-Unsafe, this mark is applied to
              writers only. Writers remain MT-Unsafe to call, but
              the then-mandatory constness of objects they modify
              enables readers to be regarded as MT-Safe (as long as
              no other reasons for them to be unsafe remain), since
              the lack of synchronization is not a problem when the
              objects are effectively constant.
The identifier that follows the const mark will
              appear by itself as a safety note in readers.
              Programs that wish to work around this safety issue,
              so as to call writers, may use a non-recursive
              read-write lock associated with the identifier, and
              guard all
              calls to functions marked with const followed by the
              identifier with a write lock, and all calls to
              functions marked with the identifier by itself with a
              read lock.
sigFunctions marked with sig as a MT-Safety
              issue may temporarily install a signal handler for
              internal purposes, which may interfere with other
              uses of the signal, identified after a colon.
This safety problem can be worked around by ensuring that no other uses of the signal will take place for the duration of the call. Holding a non-recursive mutex while calling all functions that use the same temporary signal; blocking that signal before the call and resetting its handler afterwards is recommended.
termFunctions marked with term as an MT-Safety
              issue may change the terminal settings in the
              recommended way, namely: call tcgetattr(3),
              modify some flags, and then call tcsetattr(3), this
              creates a window in which changes made by other
              threads are lost. Thus, functions marked with
              term are
              MT-Unsafe.
It is thus advisable for applications using the
              terminal to avoid concurrent and reentrant
              interactions with it, by not using it in signal
              handlers or blocking signals that might use it, and
              holding a lock while calling these functions and
              interacting with the terminal. This lock should also
              be used for mutual exclusion with functions marked
              with race:tcattr(fd),
              where fd is
              a file descriptor for the controlling terminal. The
              caller may use a single mutex for simplicity, or use
              one mutex per terminal, even if referenced by
              different file descriptors.
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:
localeFunctions annotated with locale as an
              MT-Safety issue read from the locale object without
              any form of synchronization. Functions annotated with
              locale
              called concurrently with locale changes may behave in
              ways that do not correspond to any of the locales
              active during their execution, but an unpredictable
              mix thereof.
We do not mark these functions as MT-Unsafe,
              however, because functions that modify the locale
              object are marked with const:locale and
              regarded as unsafe. Being unsafe, the latter are not
              to be called when multiple threads are running or
              asynchronous signals are enabled, and so the locale
              can be considered effectively constant in these
              contexts, which makes the former safe.
envFunctions marked with env as an MT-Safety
              issue access the environment with getenv(3) or
              similar, without any guards to ensure safety in the
              presence of concurrent modifications.
We do not mark these functions as MT-Unsafe,
              however, because functions that modify the
              environment are all marked with const:env and
              regarded as unsafe. Being unsafe, the latter are not
              to be called when multiple threads are running or
              asynchronous signals are enabled, and so the
              environment can be considered effectively constant in
              these contexts, which makes the former safe.
hostidThe function marked with hostid as an
              MT-Safety issue reads from the system-wide data
              structures that hold the "host ID" of the machine.
              These data structures cannot generally be modified
              atomically. Since it is expected that the "host ID"
              will not normally change, the function that reads
              from it (gethostid(3)) is
              regarded as safe, whereas the function that modifies
              it (sethostid(3)) is
              marked with const:hostid,
              indicating it may require special care if it is to be
              called. In this specific case, the special care
              amounts to system-wide (not merely intra-process)
              coordination.
sigintrFunctions marked with sigintr as an
              MT-Safety issue access the GNU C Library _sigintr internal
              data structure without any guards to ensure safety in
              the presence of concurrent modifications.
We do not mark these functions as MT-Unsafe,
              however, because functions that modify this data
              structure are all marked with const:sigintr and
              regarded as unsafe. Being unsafe, the latter are not
              to be called when multiple threads are running or
              asynchronous signals are enabled, and so the data
              structure can be considered effectively constant in
              these contexts, which makes the former safe.
cwdFunctions marked with cwd as an MT-Safety
              issue 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., nftw(3) with
              FTW_CHDIR), avoiding
              the option may be a good alternative to using full
              pathnames or file descriptor-relative (e.g.,
              openat(2)) system
              calls.
:identifierAnnotations may sometimes be followed by
              identifiers, intended to group several functions
              that, for example, access the data structures in an
              unsafe way, as in race and const, or to provide
              more specific information, such as naming a signal in
              a function marked with sig. It is envisioned
              that it may be applied to lock and corrupt as well in
              the future.
In most cases, the identifier will name a set of
              functions, but it may name global objects or function
              arguments, or identifiable properties or logical
              components associated with them, with a notation such
              as, for example, :buf(arg) to denote a
              buffer associated with the argument arg, or :tcattr(fd) to denote
              the terminal attributes of a file descriptor
              fd.
The most common use for identifiers is to provide logical groups of functions and arguments that need to be protected by the same synchronization primitive in order to ensure safe operation in a given context.
/conditionSome safety annotations may be conditional, in
              that they only apply if a boolean expression
              involving arguments, global variables or even the
              underlying kernel evaluates to true. For example,
              /!ps and /one_per_line indicate the
              preceding marker only applies when argument
              ps is NULL,
              or global variable one_per_line is
              nonzero.
When all marks that render a function unsafe are adorned with such conditions, and none of the named conditions hold, then the function can be regarded as safe.
This page is part of release 4.07 of the Linux man-pages project. A
      description of the project, information about reporting bugs,
      and the latest version of this page, can be found at
      https://www.kernel.org/doc/man−pages/.
| Copyright (c) 2014, Red Hat, Inc Written by Alexandre Oliva <aolivaredhat.com> %%%LICENSE_START(GPLv2+_DOC_FULL) This is free documentation; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU General Public License's references to "object code" and "executables" are to be interpreted as the output of any document formatting or typesetting system, including intermediate and printed output. This manual is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this manual; if not, see <http://www.gnu.org/licenses/>. %%%LICENSE_END |