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