]> git.ipfire.org Git - thirdparty/man-pages.git/blob - man3/pthread_cleanup_push.3
sched_setattr.2: Minor tweaks to Claudio Scordino's patch
[thirdparty/man-pages.git] / man3 / pthread_cleanup_push.3
1 .\" Copyright (c) 2008 Linux Foundation, written by Michael Kerrisk
2 .\" <mtk.manpages@gmail.com>
3 .\"
4 .\" %%%LICENSE_START(VERBATIM)
5 .\" Permission is granted to make and distribute verbatim copies of this
6 .\" manual provided the copyright notice and this permission notice are
7 .\" preserved on all copies.
8 .\"
9 .\" Permission is granted to copy and distribute modified versions of this
10 .\" manual under the conditions for verbatim copying, provided that the
11 .\" entire resulting derived work is distributed under the terms of a
12 .\" permission notice identical to this one.
13 .\"
14 .\" Since the Linux kernel and libraries are constantly changing, this
15 .\" manual page may be incorrect or out-of-date. The author(s) assume no
16 .\" responsibility for errors or omissions, or for damages resulting from
17 .\" the use of the information contained herein. The author(s) may not
18 .\" have taken the same level of care in the production of this manual,
19 .\" which is licensed free of charge, as they might when working
20 .\" professionally.
21 .\"
22 .\" Formatted or processed versions of this manual, if unaccompanied by
23 .\" the source, must acknowledge the copyright and authors of this work.
24 .\" %%%LICENSE_END
25 .\"
26 .TH PTHREAD_CLEANUP_PUSH 3 2017-09-15 "Linux" "Linux Programmer's Manual"
27 .SH NAME
28 pthread_cleanup_push, pthread_cleanup_pop \- push and pop
29 thread cancellation clean-up handlers
30 .SH SYNOPSIS
31 .nf
32 .B #include <pthread.h>
33 .PP
34 .BI "void pthread_cleanup_push(void (*" routine ")(void *),"
35 .BI " void *" arg );
36 .BI "void pthread_cleanup_pop(int " execute );
37 .PP
38 Compile and link with \fI\-pthread\fP.
39 .fi
40 .SH DESCRIPTION
41 These functions manipulate the calling thread's stack of
42 thread-cancellation clean-up handlers.
43 A clean-up handler is a function that is automatically executed
44 when a thread is canceled (or in various other circumstances
45 described below);
46 it might, for example, unlock a mutex so that
47 it becomes available to other threads in the process.
48 .PP
49 The
50 .BR pthread_cleanup_push ()
51 function pushes
52 .I routine
53 onto the top of the stack of clean-up handlers.
54 When
55 .I routine
56 is later invoked, it will be given
57 .I arg
58 as its argument.
59 .PP
60 The
61 .BR pthread_cleanup_pop ()
62 function removes the routine at the top of the stack of clean-up handlers,
63 and optionally executes it if
64 .I execute
65 is nonzero.
66 .PP
67 A cancellation clean-up handler is popped from the stack
68 and executed in the following circumstances:
69 .IP 1. 3
70 When a thread is canceled,
71 all of the stacked clean-up handlers are popped and executed in
72 the reverse of the order in which they were pushed onto the stack.
73 .IP 2.
74 When a thread terminates by calling
75 .BR pthread_exit (3),
76 all clean-up handlers are executed as described in the preceding point.
77 (Clean-up handlers are
78 .I not
79 called if the thread terminates by
80 performing a
81 .I return
82 from the thread start function.)
83 .IP 3.
84 When a thread calls
85 .BR pthread_cleanup_pop ()
86 with a nonzero
87 .I execute
88 argument, the top-most clean-up handler is popped and executed.
89 .PP
90 POSIX.1 permits
91 .BR pthread_cleanup_push ()
92 and
93 .BR pthread_cleanup_pop ()
94 to be implemented as macros that expand to text
95 containing \(aq\fB{\fP\(aq and \(aq\fB}\fP\(aq, respectively.
96 For this reason, the caller must ensure that calls to these
97 functions are paired within the same function,
98 and at the same lexical nesting level.
99 (In other words, a clean-up handler is established only
100 during the execution of a specified section of code.)
101 .PP
102 Calling
103 .BR longjmp (3)
104 .RB ( siglongjmp (3))
105 produces undefined results if any call has been made to
106 .BR pthread_cleanup_push ()
107 or
108 .BR pthread_cleanup_pop ()
109 without the matching call of the pair since the jump buffer
110 was filled by
111 .BR setjmp (3)
112 .RB ( sigsetjmp (3)).
113 Likewise, calling
114 .BR longjmp (3)
115 .RB ( siglongjmp (3))
116 from inside a clean-up handler produces undefined results
117 unless the jump buffer was also filled by
118 .BR setjmp (3)
119 .RB ( sigsetjmp (3))
120 inside the handler.
121 .SH RETURN VALUE
122 These functions do not return a value.
123 .SH ERRORS
124 There are no errors.
125 .\" SH VERSIONS
126 .\" Available since glibc 2.0
127 .SH ATTRIBUTES
128 For an explanation of the terms used in this section, see
129 .BR attributes (7).
130 .TS
131 allbox;
132 lbw23 lb lb
133 l l l.
134 Interface Attribute Value
135 T{
136 .BR pthread_cleanup_push (),
137 .BR pthread_cleanup_pop ()
138 T} Thread safety MT-Safe
139 .TE
140 .sp 1
141 .SH CONFORMING TO
142 POSIX.1-2001, POSIX.1-2008.
143 .SH NOTES
144 On Linux, the
145 .BR pthread_cleanup_push ()
146 and
147 .BR pthread_cleanup_pop ()
148 functions
149 .I are
150 implemented as macros that expand to text
151 containing \(aq\fB{\fP\(aq and \(aq\fB}\fP\(aq, respectively.
152 This means that variables declared within the scope of
153 paired calls to these functions will be visible within only that scope.
154 .PP
155 POSIX.1
156 .\" The text was actually added in the 2004 TC2
157 says that the effect of using
158 .IR return ,
159 .IR break ,
160 .IR continue ,
161 or
162 .IR goto
163 to prematurely leave a block bracketed
164 .BR pthread_cleanup_push ()
165 and
166 .BR pthread_cleanup_pop ()
167 is undefined.
168 Portable applications should avoid doing this.
169 .SH EXAMPLE
170 The program below provides a simple example of the use of the functions
171 described in this page.
172 The program creates a thread that executes a loop bracketed by
173 .BR pthread_cleanup_push ()
174 and
175 .BR pthread_cleanup_pop ().
176 This loop increments a global variable,
177 .IR cnt ,
178 once each second.
179 Depending on what command-line arguments are supplied,
180 the main thread sends the other thread a cancellation request,
181 or sets a global variable that causes the other thread
182 to exit its loop and terminate normally (by doing a
183 .IR return ).
184 .PP
185 In the following shell session,
186 the main thread sends a cancellation request to the other thread:
187 .PP
188 .in +4n
189 .EX
190 $ \fB./a.out\fP
191 New thread started
192 cnt = 0
193 cnt = 1
194 Canceling thread
195 Called clean-up handler
196 Thread was canceled; cnt = 0
197 .EE
198 .in
199 .PP
200 From the above, we see that the thread was canceled,
201 and that the cancellation clean-up handler was called
202 and it reset the value of the global variable
203 .I cnt
204 to 0.
205 .PP
206 In the next run, the main program sets a
207 global variable that causes other thread to terminate normally:
208 .PP
209 .in +4n
210 .EX
211 $ \fB./a.out x\fP
212 New thread started
213 cnt = 0
214 cnt = 1
215 Thread terminated normally; cnt = 2
216 .EE
217 .in
218 .PP
219 From the above, we see that the clean-up handler was not executed (because
220 .I cleanup_pop_arg
221 was 0), and therefore the value of
222 .I cnt
223 was not reset.
224 .PP
225 In the next run, the main program sets a global variable that
226 causes the other thread to terminate normally,
227 and supplies a nonzero value for
228 .IR cleanup_pop_arg :
229 .PP
230 .in +4n
231 .EX
232 $ \fB./a.out x 1\fP
233 New thread started
234 cnt = 0
235 cnt = 1
236 Called clean-up handler
237 Thread terminated normally; cnt = 0
238 .EE
239 .in
240 .PP
241 In the above, we see that although the thread was not canceled,
242 the clean-up handler was executed, because the argument given to
243 .BR pthread_cleanup_pop ()
244 was nonzero.
245 .SS Program source
246 \&
247 .EX
248 #include <pthread.h>
249 #include <sys/types.h>
250 #include <stdio.h>
251 #include <stdlib.h>
252 #include <unistd.h>
253 #include <errno.h>
254
255 #define handle_error_en(en, msg) \e
256 do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
257
258 static int done = 0;
259 static int cleanup_pop_arg = 0;
260 static int cnt = 0;
261
262 static void
263 cleanup_handler(void *arg)
264 {
265 printf("Called clean\-up handler\en");
266 cnt = 0;
267 }
268
269 static void *
270 thread_start(void *arg)
271 {
272 time_t start, curr;
273
274 printf("New thread started\en");
275
276 pthread_cleanup_push(cleanup_handler, NULL);
277
278 curr = start = time(NULL);
279
280 while (!done) {
281 pthread_testcancel(); /* A cancellation point */
282 if (curr < time(NULL)) {
283 curr = time(NULL);
284 printf("cnt = %d\en", cnt); /* A cancellation point */
285 cnt++;
286 }
287 }
288
289 pthread_cleanup_pop(cleanup_pop_arg);
290 return NULL;
291 }
292
293 int
294 main(int argc, char *argv[])
295 {
296 pthread_t thr;
297 int s;
298 void *res;
299
300 s = pthread_create(&thr, NULL, thread_start, NULL);
301 if (s != 0)
302 handle_error_en(s, "pthread_create");
303
304 sleep(2); /* Allow new thread to run a while */
305
306 if (argc > 1) {
307 if (argc > 2)
308 cleanup_pop_arg = atoi(argv[2]);
309 done = 1;
310
311 } else {
312 printf("Canceling thread\en");
313 s = pthread_cancel(thr);
314 if (s != 0)
315 handle_error_en(s, "pthread_cancel");
316 }
317
318 s = pthread_join(thr, &res);
319 if (s != 0)
320 handle_error_en(s, "pthread_join");
321
322 if (res == PTHREAD_CANCELED)
323 printf("Thread was canceled; cnt = %d\en", cnt);
324 else
325 printf("Thread terminated normally; cnt = %d\en", cnt);
326 exit(EXIT_SUCCESS);
327 }
328 .EE
329 .SH SEE ALSO
330 .BR pthread_cancel (3),
331 .BR pthread_cleanup_push_defer_np (3),
332 .BR pthread_setcancelstate (3),
333 .BR pthread_testcancel (3),
334 .BR pthreads (7)