1attributes(7) Miscellaneous Information Manual attributes(7)
2
3
4
6 attributes - POSIX safety concepts
7
9 Note: the text of this man page is based on the material taken from the
10 "POSIX Safety Concepts" section of the GNU C Library manual. Further
11 details on the topics described here can be found in that manual.
12
13 Various function manual pages include a section ATTRIBUTES that de‐
14 scribes the safety of calling the function in various contexts. This
15 section annotates functions with the following safety markings:
16
17 MT-Safe
18 MT-Safe or Thread-Safe functions are safe to call in the pres‐
19 ence of other threads. MT, in MT-Safe, stands for Multi Thread.
20
21 Being MT-Safe does not imply a function is atomic, nor that it
22 uses any of the memory synchronization mechanisms POSIX exposes
23 to users. It is even possible that calling MT-Safe functions in
24 sequence does not yield an MT-Safe combination. For example,
25 having a thread call two MT-Safe functions one right after the
26 other does not guarantee behavior equivalent to atomic execution
27 of a combination of both functions, since concurrent calls in
28 other threads may interfere in a destructive way.
29
30 Whole-program optimizations that could inline functions across
31 library interfaces may expose unsafe reordering, and so perform‐
32 ing inlining across the GNU C Library interface is not recom‐
33 mended. The documented MT-Safety status is not guaranteed under
34 whole-program optimization. However, functions defined in user-
35 visible headers are designed to be safe for inlining.
36
37 MT-Unsafe
38 MT-Unsafe functions are not safe to call in a multithreaded pro‐
39 grams.
40
41 Other keywords that appear in safety notes are defined in subsequent
42 sections.
43
44 Conditionally safe features
45 For some features that make functions unsafe to call in certain con‐
46 texts, there are known ways to avoid the safety problem other than re‐
47 fraining from calling the function altogether. The keywords that fol‐
48 low refer to such features, and each of their definitions indicates how
49 the whole program needs to be constrained in order to remove the safety
50 problem indicated by the keyword. Only when all the reasons that make
51 a function unsafe are observed and addressed, by applying the docu‐
52 mented constraints, does the function become safe to call in a context.
53
54 init Functions marked with init as an MT-Unsafe feature perform MT-
55 Unsafe initialization when they are first called.
56
57 Calling such a function at least once in single-threaded mode
58 removes this specific cause for the function to be regarded as
59 MT-Unsafe. If no other cause for that remains, the function can
60 then be safely called after other threads are started.
61
62 race Functions annotated with race as an MT-Safety issue operate on
63 objects in ways that may cause data races or similar forms of
64 destructive interference out of concurrent execution. In some
65 cases, the objects are passed to the functions by users; in oth‐
66 ers, they are used by the functions to return values to users;
67 in others, they are not even exposed to users.
68
69 const Functions marked with const as an MT-Safety issue non-atomically
70 modify internal objects that are better regarded as constant,
71 because a substantial portion of the GNU C Library accesses them
72 without synchronization. Unlike race, which causes both readers
73 and writers of internal objects to be regarded as MT-Unsafe,
74 this mark is applied to writers only. Writers remain MT-Unsafe
75 to call, but the then-mandatory constness of objects they modify
76 enables readers to be regarded as MT-Safe (as long as no other
77 reasons for them to be unsafe remain), since the lack of syn‐
78 chronization is not a problem when the objects are effectively
79 constant.
80
81 The identifier that follows the const mark will appear by itself
82 as a safety note in readers. Programs that wish to work around
83 this safety issue, so as to call writers, may use a non-recur‐
84 sive read-write lock associated with the identifier, and guard
85 all calls to functions marked with const followed by the identi‐
86 fier with a write lock, and all calls to functions marked with
87 the identifier by itself with a read lock.
88
89 sig Functions marked with sig as a MT-Safety issue may temporarily
90 install a signal handler for internal purposes, which may inter‐
91 fere with other uses of the signal, identified after a colon.
92
93 This safety problem can be worked around by ensuring that no
94 other uses of the signal will take place for the duration of the
95 call. Holding a non-recursive mutex while calling all functions
96 that use the same temporary signal; blocking that signal before
97 the call and resetting its handler afterwards is recommended.
98
99 term Functions marked with term as an MT-Safety issue may change the
100 terminal settings in the recommended way, namely: call tcge‐
101 tattr(3), modify some flags, and then call tcsetattr(3), this
102 creates a window in which changes made by other threads are
103 lost. Thus, functions marked with term are MT-Unsafe.
104
105 It is thus advisable for applications using the terminal to
106 avoid concurrent and reentrant interactions with it, by not us‐
107 ing it in signal handlers or blocking signals that might use it,
108 and holding a lock while calling these functions and interacting
109 with the terminal. This lock should also be used for mutual ex‐
110 clusion with functions marked with race:tcattr(fd), where fd is
111 a file descriptor for the controlling terminal. The caller may
112 use a single mutex for simplicity, or use one mutex per termi‐
113 nal, even if referenced by different file descriptors.
114
115 Other safety remarks
116 Additional keywords may be attached to functions, indicating features
117 that do not make a function unsafe to call, but that may need to be
118 taken into account in certain classes of programs:
119
120 locale Functions annotated with locale as an MT-Safety issue read from
121 the locale object without any form of synchronization. Func‐
122 tions annotated with locale called concurrently with locale
123 changes may behave in ways that do not correspond to any of the
124 locales active during their execution, but an unpredictable mix
125 thereof.
126
127 We do not mark these functions as MT-Unsafe, however, because
128 functions that modify the locale object are marked with
129 const:locale and regarded as unsafe. Being unsafe, the latter
130 are not to be called when multiple threads are running or asyn‐
131 chronous signals are enabled, and so the locale can be consid‐
132 ered effectively constant in these contexts, which makes the
133 former safe.
134
135 env Functions marked with env as an MT-Safety issue access the envi‐
136 ronment with getenv(3) or similar, without any guards to ensure
137 safety in the presence of concurrent modifications.
138
139 We do not mark these functions as MT-Unsafe, however, because
140 functions that modify the environment are all marked with
141 const:env and regarded as unsafe. Being unsafe, the latter are
142 not to be called when multiple threads are running or asynchro‐
143 nous signals are enabled, and so the environment can be consid‐
144 ered effectively constant in these contexts, which makes the
145 former safe.
146
147 hostid The function marked with hostid as an MT-Safety issue reads from
148 the system-wide data structures that hold the "host ID" of the
149 machine. These data structures cannot generally be modified
150 atomically. Since it is expected that the "host ID" will not
151 normally change, the function that reads from it (gethostid(3))
152 is regarded as safe, whereas the function that modifies it
153 (sethostid(3)) is marked with const:hostid, indicating it may
154 require special care if it is to be called. In this specific
155 case, the special care amounts to system-wide (not merely intra-
156 process) coordination.
157
158 sigintr
159 Functions marked with sigintr as an MT-Safety issue access the
160 GNU C Library _sigintr internal data structure without any
161 guards to ensure safety in the presence of concurrent modifica‐
162 tions.
163
164 We do not mark these functions as MT-Unsafe, however, because
165 functions that modify this data structure are all marked with
166 const:sigintr and regarded as unsafe. Being unsafe, the latter
167 are not to be called when multiple threads are running or asyn‐
168 chronous signals are enabled, and so the data structure can be
169 considered effectively constant in these contexts, which makes
170 the former safe.
171
172 cwd Functions marked with cwd as an MT-Safety issue may temporarily
173 change the current working directory during their execution,
174 which may cause relative pathnames to be resolved in unexpected
175 ways in other threads or within asynchronous signal or cancela‐
176 tion handlers.
177
178 This is not enough of a reason to mark so-marked functions as
179 MT-Unsafe, but when this behavior is optional (e.g., nftw(3)
180 with FTW_CHDIR), avoiding the option may be a good alternative
181 to using full pathnames or file descriptor-relative (e.g., ope‐
182 nat(2)) system calls.
183
184 :identifier
185 Annotations may sometimes be followed by identifiers, intended
186 to group several functions that, for example, access the data
187 structures in an unsafe way, as in race and const, or to provide
188 more specific information, such as naming a signal in a function
189 marked with sig. It is envisioned that it may be applied to
190 lock and corrupt as well in the future.
191
192 In most cases, the identifier will name a set of functions, but
193 it may name global objects or function arguments, or identifi‐
194 able properties or logical components associated with them, with
195 a notation such as, for example, :buf(arg) to denote a buffer
196 associated with the argument arg, or :tcattr(fd) to denote the
197 terminal attributes of a file descriptor fd.
198
199 The most common use for identifiers is to provide logical groups
200 of functions and arguments that need to be protected by the same
201 synchronization primitive in order to ensure safe operation in a
202 given context.
203
204 /condition
205 Some safety annotations may be conditional, in that they only
206 apply if a boolean expression involving arguments, global vari‐
207 ables or even the underlying kernel evaluates to true. For ex‐
208 ample, /!ps and /one_per_line indicate the preceding marker only
209 applies when argument ps is NULL, or global variable
210 one_per_line is nonzero.
211
212 When all marks that render a function unsafe are adorned with
213 such conditions, and none of the named conditions hold, then the
214 function can be regarded as safe.
215
217 pthreads(7), signal-safety(7)
218
219
220
221Linux man-pages 6.04 2023-03-18 attributes(7)