]> git.ipfire.org Git - thirdparty/man-pages.git/blob - man3/pthread_cleanup_push.3
a590203efaddb5a0217922ab7f334ac21071d718
[thirdparty/man-pages.git] / man3 / pthread_cleanup_push.3
1 .\" Copyright (c) 2008 Linux Foundation, written by Michael Kerrisk
2 .\" <mtk.manpages@gmail.com>
3 .\"
4 .\" SPDX-License-Identifier: Linux-man-pages-copyleft
5 .\"
6 .TH PTHREAD_CLEANUP_PUSH 3 2021-03-22 "Linux man-pages (unreleased)" "Linux Programmer's Manual"
7 .SH NAME
8 pthread_cleanup_push, pthread_cleanup_pop \- push and pop
9 thread cancelation clean-up handlers
10 .SH LIBRARY
11 POSIX threads library
12 .RI ( libpthread ", " \-lpthread )
13 .SH SYNOPSIS
14 .nf
15 .B #include <pthread.h>
16 .PP
17 .BI "void pthread_cleanup_push(void (*" routine ")(void *), void *" arg );
18 .BI "void pthread_cleanup_pop(int " execute );
19 .fi
20 .SH DESCRIPTION
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
25 described below);
26 it might, for example, unlock a mutex so that
27 it becomes available to other threads in the process.
28 .PP
29 The
30 .BR pthread_cleanup_push ()
31 function pushes
32 .I routine
33 onto the top of the stack of clean-up handlers.
34 When
35 .I routine
36 is later invoked, it will be given
37 .I arg
38 as its argument.
39 .PP
40 The
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
44 .I execute
45 is nonzero.
46 .PP
47 A cancelation clean-up handler is popped from the stack
48 and executed in the following circumstances:
49 .IP 1. 3
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.
53 .IP 2.
54 When a thread terminates by calling
55 .BR pthread_exit (3),
56 all clean-up handlers are executed as described in the preceding point.
57 (Clean-up handlers are
58 .I not
59 called if the thread terminates by
60 performing a
61 .I return
62 from the thread start function.)
63 .IP 3.
64 When a thread calls
65 .BR pthread_cleanup_pop ()
66 with a nonzero
67 .I execute
68 argument, the top-most clean-up handler is popped and executed.
69 .PP
70 POSIX.1 permits
71 .BR pthread_cleanup_push ()
72 and
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.)
81 .PP
82 Calling
83 .BR longjmp (3)
84 .RB ( siglongjmp (3))
85 produces undefined results if any call has been made to
86 .BR pthread_cleanup_push ()
87 or
88 .BR pthread_cleanup_pop ()
89 without the matching call of the pair since the jump buffer
90 was filled by
91 .BR setjmp (3)
92 .RB ( sigsetjmp (3)).
93 Likewise, calling
94 .BR longjmp (3)
95 .RB ( siglongjmp (3))
96 from inside a clean-up handler produces undefined results
97 unless the jump buffer was also filled by
98 .BR setjmp (3)
99 .RB ( sigsetjmp (3))
100 inside the handler.
101 .SH RETURN VALUE
102 These functions do not return a value.
103 .SH ERRORS
104 There are no errors.
105 .\" SH VERSIONS
106 .\" Available since glibc 2.0
107 .SH ATTRIBUTES
108 For an explanation of the terms used in this section, see
109 .BR attributes (7).
110 .ad l
111 .nh
112 .TS
113 allbox;
114 lbx lb lb
115 l l l.
116 Interface Attribute Value
117 T{
118 .BR pthread_cleanup_push (),
119 .BR pthread_cleanup_pop ()
120 T} Thread safety MT-Safe
121 .TE
122 .hy
123 .ad
124 .sp 1
125 .SH STANDARDS
126 POSIX.1-2001, POSIX.1-2008.
127 .SH NOTES
128 On Linux, the
129 .BR pthread_cleanup_push ()
130 and
131 .BR pthread_cleanup_pop ()
132 functions
133 .I are
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.
138 .PP
139 POSIX.1
140 .\" The text was actually added in the 2004 TC2
141 says that the effect of using
142 .IR return ,
143 .IR break ,
144 .IR continue ,
145 or
146 .I goto
147 to prematurely leave a block bracketed
148 .BR pthread_cleanup_push ()
149 and
150 .BR pthread_cleanup_pop ()
151 is undefined.
152 Portable applications should avoid doing this.
153 .SH EXAMPLES
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 ()
158 and
159 .BR pthread_cleanup_pop ().
160 This loop increments a global variable,
161 .IR cnt ,
162 once each second.
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
167 .IR return ).
168 .PP
169 In the following shell session,
170 the main thread sends a cancelation request to the other thread:
171 .PP
172 .in +4n
173 .EX
174 $ \fB./a.out\fP
175 New thread started
176 cnt = 0
177 cnt = 1
178 Canceling thread
179 Called clean\-up handler
180 Thread was canceled; cnt = 0
181 .EE
182 .in
183 .PP
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
187 .I cnt
188 to 0.
189 .PP
190 In the next run, the main program sets a
191 global variable that causes other thread to terminate normally:
192 .PP
193 .in +4n
194 .EX
195 $ \fB./a.out x\fP
196 New thread started
197 cnt = 0
198 cnt = 1
199 Thread terminated normally; cnt = 2
200 .EE
201 .in
202 .PP
203 From the above, we see that the clean-up handler was not executed (because
204 .I cleanup_pop_arg
205 was 0), and therefore the value of
206 .I cnt
207 was not reset.
208 .PP
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 :
213 .PP
214 .in +4n
215 .EX
216 $ \fB./a.out x 1\fP
217 New thread started
218 cnt = 0
219 cnt = 1
220 Called clean\-up handler
221 Thread terminated normally; cnt = 0
222 .EE
223 .in
224 .PP
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 ()
228 was nonzero.
229 .SS Program source
230 \&
231 .EX
232 #include <pthread.h>
233 #include <sys/types.h>
234 #include <stdio.h>
235 #include <stdlib.h>
236 #include <unistd.h>
237 #include <errno.h>
238
239 #define handle_error_en(en, msg) \e
240 do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
241
242 static int done = 0;
243 static int cleanup_pop_arg = 0;
244 static int cnt = 0;
245
246 static void
247 cleanup_handler(void *arg)
248 {
249 printf("Called clean\-up handler\en");
250 cnt = 0;
251 }
252
253 static void *
254 thread_start(void *arg)
255 {
256 time_t start, curr;
257
258 printf("New thread started\en");
259
260 pthread_cleanup_push(cleanup_handler, NULL);
261
262 curr = start = time(NULL);
263
264 while (!done) {
265 pthread_testcancel(); /* A cancelation point */
266 if (curr < time(NULL)) {
267 curr = time(NULL);
268 printf("cnt = %d\en", cnt); /* A cancelation point */
269 cnt++;
270 }
271 }
272
273 pthread_cleanup_pop(cleanup_pop_arg);
274 return NULL;
275 }
276
277 int
278 main(int argc, char *argv[])
279 {
280 pthread_t thr;
281 int s;
282 void *res;
283
284 s = pthread_create(&thr, NULL, thread_start, NULL);
285 if (s != 0)
286 handle_error_en(s, "pthread_create");
287
288 sleep(2); /* Allow new thread to run a while */
289
290 if (argc > 1) {
291 if (argc > 2)
292 cleanup_pop_arg = atoi(argv[2]);
293 done = 1;
294
295 } else {
296 printf("Canceling thread\en");
297 s = pthread_cancel(thr);
298 if (s != 0)
299 handle_error_en(s, "pthread_cancel");
300 }
301
302 s = pthread_join(thr, &res);
303 if (s != 0)
304 handle_error_en(s, "pthread_join");
305
306 if (res == PTHREAD_CANCELED)
307 printf("Thread was canceled; cnt = %d\en", cnt);
308 else
309 printf("Thread terminated normally; cnt = %d\en", cnt);
310 exit(EXIT_SUCCESS);
311 }
312 .EE
313 .SH SEE ALSO
314 .BR pthread_cancel (3),
315 .BR pthread_cleanup_push_defer_np (3),
316 .BR pthread_setcancelstate (3),
317 .BR pthread_testcancel (3),
318 .BR pthreads (7)