1 .\" Copyright (c) 2008 Linux Foundation, written by Michael Kerrisk
2 .\" <mtk.manpages@gmail.com>
4 .\" Permission is granted to make and distribute verbatim copies of this
5 .\" manual provided the copyright notice and this permission notice are
6 .\" preserved on all copies.
8 .\" Permission is granted to copy and distribute modified versions of this
9 .\" manual under the conditions for verbatim copying, provided that the
10 .\" entire resulting derived work is distributed under the terms of a
11 .\" permission notice identical to this one.
13 .\" Since the Linux kernel and libraries are constantly changing, this
14 .\" manual page may be incorrect or out-of-date. The author(s) assume no
15 .\" responsibility for errors or omissions, or for damages resulting from
16 .\" the use of the information contained herein. The author(s) may not
17 .\" have taken the same level of care in the production of this manual,
18 .\" which is licensed free of charge, as they might when working
21 .\" Formatted or processed versions of this manual, if unaccompanied by
22 .\" the source, must acknowledge the copyright and authors of this work.
24 .TH PTHREAD_CLEANUP_PUSH 3 2008-11-24 "Linux" "Linux Programmer's Manual"
26 pthread_cleanup_push, pthread_cleanup_pop \- push and pop
27 thread cancellation clean-up handlers
30 .B #include <pthread.h>
32 .BI "void pthread_cleanup_push(void (*" routine ")(void *),"
34 .BI "void pthread_cleanup_pop(int " execute );
36 Compile and link with \fI\-pthread\fP.
38 These functions manipulate the calling thread's stack of
39 thread-cancellation clean-up handlers.
40 A clean-up handler is a function that is automatically executed
41 when a thread is canceled (or in various other circumstances
43 it might, for example, unlock a mutex so that
44 it becomes available to other threads in the process.
47 .BR pthread_cleanup_push ()
50 onto the top of the stack of clean-up handlers.
53 is later invoked, it will be given
58 .BR pthread_cleanup_pop ()
59 function removes the routine at the top of the stack of clean-up handlers,
60 and optionally executes it if
64 A cancellation clean-up handler is popped from the stack
65 and executed in the following circumstances:
67 When a thread is canceled,
68 all of the stacked clean-up handlers are popped and executed in
69 the reverse of the order in which they were pushed onto the stack.
71 When a thread terminates by calling
73 all clean-up handlers are executed as described in the preceding point.
74 (Clean-up handlers are \fInot\fP called if the thread terminates by
77 from the thread start function.)
80 .BR pthread_cleanup_pop ()
83 argument, the top-most clean-up handler is popped and executed.
86 .BR pthread_cleanup_push ()
88 .BR pthread_cleanup_pop ()
89 to be implemented as macros that expand to text
90 containing \(aq\fB{\fP\(aq and \(aq\fB}\fP\(aq, respectively.
91 For this reason, the caller must ensure that calls to these
92 functions are paired within the same function,
93 and at the same lexical nesting level.
94 (In other words, a clean-up handler is only established
95 during the execution of a specified section of code.)
100 produces undefined results if any call has been made to
101 .BR pthread_cleanup_push ()
103 .BR pthread_cleanup_pop ()
104 without the matching call of the pair since the jump buffer
107 .RB ( sigsetjmp (3)).
110 .RB ( siglongjmp (3))
111 from inside a clean-up handler produces undefined results
112 unless the jump buffer was also filled by
117 These functions do not return a value.
121 .\" Available since glibc 2.0
126 .BR pthread_cleanup_push ()
128 .BR pthread_cleanup_pop ()
129 functions \fIare\fP implemented as macros that expand to text
130 containing \(aq\fB{\fP\(aq and \(aq\fB}\fP\(aq, respectively.
131 This means that variables declared within the scope of
132 paired calls to these functions will only be visible within that scope.
135 .\" The text was actually added in the 2004 TC2
136 says that the effect of using
142 to prematurely leave a block bracketed
143 .BR pthread_cleanup_push ()
145 .BR pthread_cleanup_pop ()
147 Portable applications should avoid doing this.
149 The program below provides a simple example of the use of the functions
150 described in this page.
151 The program creates a thread that executes a loop bracketed by
152 .BR pthread_cleanup_push ()
154 .BR pthread_cleanup_pop ().
155 This loop increments a global variable,
158 Depending on what command-line arguments are supplied,
159 the main thread sends the other thread a cancellation request,
160 or sets a global variable that causes the other thread
161 to exit its loop and terminate normally (by doing a
164 In the following shell session,
165 the main thread sends a cancellation request to the other thread:
174 Called clean-up handler
175 Thread was canceled; cnt = 0
179 From the above, we see that the thread was canceled,
180 and that the cancellation clean-up handler was called
181 and it reset the value of the global variable
185 In the next run, the main program sets a
186 global variable that causes other thread to terminate normally:
194 Thread terminated normally; cnt = 2
198 From the above, we see that the clean-up handler was not executed (because
200 was 0), and therefore the value of
204 In the next run, the main program sets a global variable that
205 causes the other thread to terminate normally,
206 and supplies a nonzero value for
207 .IR cleanup_pop_arg :
215 Called clean-up handler
216 Thread terminated normally; cnt = 0
220 In the above, we see that although the thread was not canceled,
221 the clean-up handler was executed, because the argument given to
222 .BR pthread_cleanup_pop ()
228 #include <sys/types.h>
234 #define handle_error_en(en, msg) \\
235 do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
238 static int cleanup_pop_arg = 0;
242 cleanup_handler(void *arg)
244 printf("Called clean\-up handler\\n");
249 thread_start(void *arg)
253 printf("New thread started\\n");
255 pthread_cleanup_push(cleanup_handler, NULL);
257 curr = start = time(NULL);
260 pthread_testcancel(); /* A cancellation point */
261 if (curr < time(NULL)) {
263 printf("cnt = %d\\n", cnt); /* A cancellation point */
268 pthread_cleanup_pop(cleanup_pop_arg);
273 main(int argc, char *argv[])
279 s = pthread_create(&thr, NULL, thread_start, NULL);
281 handle_error_en(s, "pthread_create");
283 sleep(2); /* Allow new thread to run a while */
287 cleanup_pop_arg = atoi(argv[2]);
291 printf("Canceling thread\\n");
292 s = pthread_cancel(thr);
294 handle_error_en(s, "pthread_cancel");
297 s = pthread_join(thr, &res);
299 handle_error_en(s, "pthread_join");
301 if (res == PTHREAD_CANCELED)
302 printf("Thread was canceled; cnt = %d\\n", cnt);
304 printf("Thread terminated normally; cnt = %d\\n", cnt);
309 .BR pthread_cancel (3),
310 .BR pthread_cleanup_push_defer_np (3),
311 .BR pthread_setcancelstate (3),
312 .BR pthread_testcancel (3),