1 .\" Copyright (c) 2008 Linux Foundation, written by Michael Kerrisk
2 .\" <mtk.manpages@gmail.com>
4 .\" SPDX-License-Identifier: Linux-man-pages-copyleft
6 .TH PTHREAD_CLEANUP_PUSH 3 2021-03-22 "Linux man-pages (unreleased)" "Linux Programmer's Manual"
8 pthread_cleanup_push, pthread_cleanup_pop \- push and pop
9 thread cancelation clean-up handlers
12 .RI ( libpthread ", " \-lpthread )
15 .B #include <pthread.h>
17 .BI "void pthread_cleanup_push(void (*" routine ")(void *), void *" arg );
18 .BI "void pthread_cleanup_pop(int " execute );
21 These functions manipulate the calling thread's stack of
22 thread-cancelation clean-up handlers.
23 A clean-up handler is a function that is automatically executed
24 when a thread is canceled (or in various other circumstances
26 it might, for example, unlock a mutex so that
27 it becomes available to other threads in the process.
30 .BR pthread_cleanup_push ()
33 onto the top of the stack of clean-up handlers.
36 is later invoked, it will be given
41 .BR pthread_cleanup_pop ()
42 function removes the routine at the top of the stack of clean-up handlers,
43 and optionally executes it if
47 A cancelation clean-up handler is popped from the stack
48 and executed in the following circumstances:
50 When a thread is canceled,
51 all of the stacked clean-up handlers are popped and executed in
52 the reverse of the order in which they were pushed onto the stack.
54 When a thread terminates by calling
56 all clean-up handlers are executed as described in the preceding point.
57 (Clean-up handlers are
59 called if the thread terminates by
62 from the thread start function.)
65 .BR pthread_cleanup_pop ()
68 argument, the top-most clean-up handler is popped and executed.
71 .BR pthread_cleanup_push ()
73 .BR pthread_cleanup_pop ()
74 to be implemented as macros that expand to text
75 containing \(aq\fB{\fP\(aq and \(aq\fB}\fP\(aq, respectively.
76 For this reason, the caller must ensure that calls to these
77 functions are paired within the same function,
78 and at the same lexical nesting level.
79 (In other words, a clean-up handler is established only
80 during the execution of a specified section of code.)
85 produces undefined results if any call has been made to
86 .BR pthread_cleanup_push ()
88 .BR pthread_cleanup_pop ()
89 without the matching call of the pair since the jump buffer
96 from inside a clean-up handler produces undefined results
97 unless the jump buffer was also filled by
102 These functions do not return a value.
106 .\" Available since glibc 2.0
108 For an explanation of the terms used in this section, see
116 Interface Attribute Value
118 .BR pthread_cleanup_push (),
119 .BR pthread_cleanup_pop ()
120 T} Thread safety MT-Safe
126 POSIX.1-2001, POSIX.1-2008.
129 .BR pthread_cleanup_push ()
131 .BR pthread_cleanup_pop ()
134 implemented as macros that expand to text
135 containing \(aq\fB{\fP\(aq and \(aq\fB}\fP\(aq, respectively.
136 This means that variables declared within the scope of
137 paired calls to these functions will be visible within only that scope.
140 .\" The text was actually added in the 2004 TC2
141 says that the effect of using
147 to prematurely leave a block bracketed
148 .BR pthread_cleanup_push ()
150 .BR pthread_cleanup_pop ()
152 Portable applications should avoid doing this.
154 The program below provides a simple example of the use of the functions
155 described in this page.
156 The program creates a thread that executes a loop bracketed by
157 .BR pthread_cleanup_push ()
159 .BR pthread_cleanup_pop ().
160 This loop increments a global variable,
163 Depending on what command-line arguments are supplied,
164 the main thread sends the other thread a cancelation request,
165 or sets a global variable that causes the other thread
166 to exit its loop and terminate normally (by doing a
169 In the following shell session,
170 the main thread sends a cancelation request to the other thread:
179 Called clean\-up handler
180 Thread was canceled; cnt = 0
184 From the above, we see that the thread was canceled,
185 and that the cancelation clean-up handler was called
186 and it reset the value of the global variable
190 In the next run, the main program sets a
191 global variable that causes other thread to terminate normally:
199 Thread terminated normally; cnt = 2
203 From the above, we see that the clean-up handler was not executed (because
205 was 0), and therefore the value of
209 In the next run, the main program sets a global variable that
210 causes the other thread to terminate normally,
211 and supplies a nonzero value for
212 .IR cleanup_pop_arg :
220 Called clean\-up handler
221 Thread terminated normally; cnt = 0
225 In the above, we see that although the thread was not canceled,
226 the clean-up handler was executed, because the argument given to
227 .BR pthread_cleanup_pop ()
233 #include <sys/types.h>
239 #define handle_error_en(en, msg) \e
240 do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
243 static int cleanup_pop_arg = 0;
247 cleanup_handler(void *arg)
249 printf("Called clean\-up handler\en");
254 thread_start(void *arg)
258 printf("New thread started\en");
260 pthread_cleanup_push(cleanup_handler, NULL);
262 curr = start = time(NULL);
265 pthread_testcancel(); /* A cancelation point */
266 if (curr < time(NULL)) {
268 printf("cnt = %d\en", cnt); /* A cancelation point */
273 pthread_cleanup_pop(cleanup_pop_arg);
278 main(int argc, char *argv[])
284 s = pthread_create(&thr, NULL, thread_start, NULL);
286 handle_error_en(s, "pthread_create");
288 sleep(2); /* Allow new thread to run a while */
292 cleanup_pop_arg = atoi(argv[2]);
296 printf("Canceling thread\en");
297 s = pthread_cancel(thr);
299 handle_error_en(s, "pthread_cancel");
302 s = pthread_join(thr, &res);
304 handle_error_en(s, "pthread_join");
306 if (res == PTHREAD_CANCELED)
307 printf("Thread was canceled; cnt = %d\en", cnt);
309 printf("Thread terminated normally; cnt = %d\en", cnt);
314 .BR pthread_cancel (3),
315 .BR pthread_cleanup_push_defer_np (3),
316 .BR pthread_setcancelstate (3),
317 .BR pthread_testcancel (3),