2 .\" Copyright (c) 2008 Linux Foundation, written by Michael Kerrisk
3 .\" <mtk.manpages@gmail.com>
5 .\" SPDX-License-Identifier: Linux-man-pages-copyleft
7 .TH pthread_cleanup_push 3 (date) "Linux man-pages (unreleased)"
9 pthread_cleanup_push, pthread_cleanup_pop \- push and pop
10 thread cancelation clean-up handlers
13 .RI ( libpthread ", " \-lpthread )
16 .B #include <pthread.h>
18 .BI "void pthread_cleanup_push(void (*" routine ")(void *), void *" arg );
19 .BI "void pthread_cleanup_pop(int " execute );
22 These functions manipulate the calling thread's stack of
23 thread-cancelation clean-up handlers.
24 A clean-up handler is a function that is automatically executed
25 when a thread is canceled (or in various other circumstances
27 it might, for example, unlock a mutex so that
28 it becomes available to other threads in the process.
31 .BR pthread_cleanup_push ()
34 onto the top of the stack of clean-up handlers.
37 is later invoked, it will be given
42 .BR pthread_cleanup_pop ()
43 function removes the routine at the top of the stack of clean-up handlers,
44 and optionally executes it if
48 A cancelation clean-up handler is popped from the stack
49 and executed in the following circumstances:
51 When a thread is canceled,
52 all of the stacked clean-up handlers are popped and executed in
53 the reverse of the order in which they were pushed onto the stack.
55 When a thread terminates by calling
57 all clean-up handlers are executed as described in the preceding point.
58 (Clean-up handlers are
60 called if the thread terminates by
63 from the thread start function.)
66 .BR pthread_cleanup_pop ()
69 argument, the top-most clean-up handler is popped and executed.
72 .BR pthread_cleanup_push ()
74 .BR pthread_cleanup_pop ()
75 to be implemented as macros that expand to text
76 containing \[aq]\fB{\fP\[aq] and \[aq]\fB}\fP\[aq], respectively.
77 For this reason, the caller must ensure that calls to these
78 functions are paired within the same function,
79 and at the same lexical nesting level.
80 (In other words, a clean-up handler is established only
81 during the execution of a specified section of code.)
86 produces undefined results if any call has been made to
87 .BR pthread_cleanup_push ()
89 .BR pthread_cleanup_pop ()
90 without the matching call of the pair since the jump buffer
97 from inside a clean-up handler produces undefined results
98 unless the jump buffer was also filled by
103 These functions do not return a value.
107 For an explanation of the terms used in this section, see
113 Interface Attribute Value
117 .BR pthread_cleanup_push (),
118 .BR pthread_cleanup_pop ()
119 T} Thread safety MT-Safe
123 .BR pthread_cleanup_push ()
125 .BR pthread_cleanup_pop ()
128 implemented as macros that expand to text
129 containing \[aq]\fB{\fP\[aq] and \[aq]\fB}\fP\[aq], respectively.
130 This means that variables declared within the scope of
131 paired calls to these functions will be visible within only that scope.
134 .\" The text was actually added in the 2004 TC2
135 says that the effect of using
141 to prematurely leave a block bracketed
142 .BR pthread_cleanup_push ()
144 .BR pthread_cleanup_pop ()
146 Portable applications should avoid doing this.
153 The program below provides a simple example of the use of the functions
154 described in this page.
155 The program creates a thread that executes a loop bracketed by
156 .BR pthread_cleanup_push ()
158 .BR pthread_cleanup_pop ().
159 This loop increments a global variable,
162 Depending on what command-line arguments are supplied,
163 the main thread sends the other thread a cancelation request,
164 or sets a global variable that causes the other thread
165 to exit its loop and terminate normally (by doing a
168 In the following shell session,
169 the main thread sends a cancelation request to the other thread:
178 Called clean\-up handler
179 Thread was canceled; cnt = 0
183 From the above, we see that the thread was canceled,
184 and that the cancelation clean-up handler was called
185 and it reset the value of the global variable
189 In the next run, the main program sets a
190 global variable that causes other thread to terminate normally:
198 Thread terminated normally; cnt = 2
202 From the above, we see that the clean-up handler was not executed (because
204 was 0), and therefore the value of
208 In the next run, the main program sets a global variable that
209 causes the other thread to terminate normally,
210 and supplies a nonzero value for
211 .IR cleanup_pop_arg :
219 Called clean\-up handler
220 Thread terminated normally; cnt = 0
224 In the above, we see that although the thread was not canceled,
225 the clean-up handler was executed, because the argument given to
226 .BR pthread_cleanup_pop ()
230 .\" SRC BEGIN (pthread_cleanup_push.c)
236 #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);
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);
315 .BR pthread_cancel (3),
316 .BR pthread_cleanup_push_defer_np (3),
317 .BR pthread_setcancelstate (3),
318 .BR pthread_testcancel (3),