1 .\" Copyright (c) 2008 Linux Foundation, written by Michael Kerrisk
2 .\" <mtk.manpages@gmail.com>
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.
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.
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
22 .\" Formatted or processed versions of this manual, if unaccompanied by
23 .\" the source, must acknowledge the copyright and authors of this work.
26 .TH PTHREAD_CLEANUP_PUSH 3 2021-03-22 "Linux" "Linux Programmer's Manual"
28 pthread_cleanup_push, pthread_cleanup_pop \- push and pop
29 thread cancellation clean-up handlers
32 .B #include <pthread.h>
34 .BI "void pthread_cleanup_push(void (*" routine ")(void *), void *" arg );
35 .BI "void pthread_cleanup_pop(int " execute );
37 Compile and link with \fI\-pthread\fP.
40 These functions manipulate the calling thread's stack of
41 thread-cancellation clean-up handlers.
42 A clean-up handler is a function that is automatically executed
43 when a thread is canceled (or in various other circumstances
45 it might, for example, unlock a mutex so that
46 it becomes available to other threads in the process.
49 .BR pthread_cleanup_push ()
52 onto the top of the stack of clean-up handlers.
55 is later invoked, it will be given
60 .BR pthread_cleanup_pop ()
61 function removes the routine at the top of the stack of clean-up handlers,
62 and optionally executes it if
66 A cancellation clean-up handler is popped from the stack
67 and executed in the following circumstances:
69 When a thread is canceled,
70 all of the stacked clean-up handlers are popped and executed in
71 the reverse of the order in which they were pushed onto the stack.
73 When a thread terminates by calling
75 all clean-up handlers are executed as described in the preceding point.
76 (Clean-up handlers are
78 called if the thread terminates by
81 from the thread start function.)
84 .BR pthread_cleanup_pop ()
87 argument, the top-most clean-up handler is popped and executed.
90 .BR pthread_cleanup_push ()
92 .BR pthread_cleanup_pop ()
93 to be implemented as macros that expand to text
94 containing \(aq\fB{\fP\(aq and \(aq\fB}\fP\(aq, respectively.
95 For this reason, the caller must ensure that calls to these
96 functions are paired within the same function,
97 and at the same lexical nesting level.
98 (In other words, a clean-up handler is established only
99 during the execution of a specified section of code.)
103 .RB ( siglongjmp (3))
104 produces undefined results if any call has been made to
105 .BR pthread_cleanup_push ()
107 .BR pthread_cleanup_pop ()
108 without the matching call of the pair since the jump buffer
111 .RB ( sigsetjmp (3)).
114 .RB ( siglongjmp (3))
115 from inside a clean-up handler produces undefined results
116 unless the jump buffer was also filled by
121 These functions do not return a value.
125 .\" Available since glibc 2.0
127 For an explanation of the terms used in this section, see
135 Interface Attribute Value
137 .BR pthread_cleanup_push (),
138 .BR pthread_cleanup_pop ()
139 T} Thread safety MT-Safe
145 POSIX.1-2001, POSIX.1-2008.
148 .BR pthread_cleanup_push ()
150 .BR pthread_cleanup_pop ()
153 implemented as macros that expand to text
154 containing \(aq\fB{\fP\(aq and \(aq\fB}\fP\(aq, respectively.
155 This means that variables declared within the scope of
156 paired calls to these functions will be visible within only that scope.
159 .\" The text was actually added in the 2004 TC2
160 says that the effect of using
166 to prematurely leave a block bracketed
167 .BR pthread_cleanup_push ()
169 .BR pthread_cleanup_pop ()
171 Portable applications should avoid doing this.
173 The program below provides a simple example of the use of the functions
174 described in this page.
175 The program creates a thread that executes a loop bracketed by
176 .BR pthread_cleanup_push ()
178 .BR pthread_cleanup_pop ().
179 This loop increments a global variable,
182 Depending on what command-line arguments are supplied,
183 the main thread sends the other thread a cancellation request,
184 or sets a global variable that causes the other thread
185 to exit its loop and terminate normally (by doing a
188 In the following shell session,
189 the main thread sends a cancellation request to the other thread:
198 Called clean\-up handler
199 Thread was canceled; cnt = 0
203 From the above, we see that the thread was canceled,
204 and that the cancellation clean-up handler was called
205 and it reset the value of the global variable
209 In the next run, the main program sets a
210 global variable that causes other thread to terminate normally:
218 Thread terminated normally; cnt = 2
222 From the above, we see that the clean-up handler was not executed (because
224 was 0), and therefore the value of
228 In the next run, the main program sets a global variable that
229 causes the other thread to terminate normally,
230 and supplies a nonzero value for
231 .IR cleanup_pop_arg :
239 Called clean\-up handler
240 Thread terminated normally; cnt = 0
244 In the above, we see that although the thread was not canceled,
245 the clean-up handler was executed, because the argument given to
246 .BR pthread_cleanup_pop ()
252 #include <sys/types.h>
258 #define handle_error_en(en, msg) \e
259 do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
262 static int cleanup_pop_arg = 0;
266 cleanup_handler(void *arg)
268 printf("Called clean\-up handler\en");
273 thread_start(void *arg)
277 printf("New thread started\en");
279 pthread_cleanup_push(cleanup_handler, NULL);
281 curr = start = time(NULL);
284 pthread_testcancel(); /* A cancellation point */
285 if (curr < time(NULL)) {
287 printf("cnt = %d\en", cnt); /* A cancellation point */
292 pthread_cleanup_pop(cleanup_pop_arg);
297 main(int argc, char *argv[])
303 s = pthread_create(&thr, NULL, thread_start, NULL);
305 handle_error_en(s, "pthread_create");
307 sleep(2); /* Allow new thread to run a while */
311 cleanup_pop_arg = atoi(argv[2]);
315 printf("Canceling thread\en");
316 s = pthread_cancel(thr);
318 handle_error_en(s, "pthread_cancel");
321 s = pthread_join(thr, &res);
323 handle_error_en(s, "pthread_join");
325 if (res == PTHREAD_CANCELED)
326 printf("Thread was canceled; cnt = %d\en", cnt);
328 printf("Thread terminated normally; cnt = %d\en", cnt);
333 .BR pthread_cancel (3),
334 .BR pthread_cleanup_push_defer_np (3),
335 .BR pthread_setcancelstate (3),
336 .BR pthread_testcancel (3),