1PTHREAD_CLEANUP_PUSH(3)    Linux Programmer's Manual   PTHREAD_CLEANUP_PUSH(3)
2
3
4

NAME

6       pthread_cleanup_push, pthread_cleanup_pop - push and pop thread cancel‐
7       lation clean-up handlers
8

SYNOPSIS

10       #include <pthread.h>
11
12       void pthread_cleanup_push(void (*routine)(void *), void *arg);
13       void pthread_cleanup_pop(int execute);
14
15       Compile and link with -pthread.
16

DESCRIPTION

18       These functions manipulate the calling thread's stack of thread-cancel‐
19       lation clean-up handlers.  A clean-up handler is a function that is au‐
20       tomatically executed when a thread is canceled  (or  in  various  other
21       circumstances  described  below); it might, for example, unlock a mutex
22       so that it becomes available to other threads in the process.
23
24       The pthread_cleanup_push() function pushes routine onto the top of  the
25       stack  of clean-up handlers.  When routine is later invoked, it will be
26       given arg as its argument.
27
28       The pthread_cleanup_pop() function removes the routine at  the  top  of
29       the  stack  of clean-up handlers, and optionally executes it if execute
30       is nonzero.
31
32       A cancellation clean-up handler is popped from the stack  and  executed
33       in the following circumstances:
34
35       1. When  a thread is canceled, all of the stacked clean-up handlers are
36          popped and executed in the reverse of the order in which  they  were
37          pushed onto the stack.
38
39       2. When  a  thread  terminates by calling pthread_exit(3), all clean-up
40          handlers are executed as described in the preceding point.   (Clean-
41          up  handlers are not called if the thread terminates by performing a
42          return from the thread start function.)
43
44       3. When a thread calls pthread_cleanup_pop() with a nonzero execute ar‐
45          gument, the top-most clean-up handler is popped and executed.
46
47       POSIX.1  permits pthread_cleanup_push() and pthread_cleanup_pop() to be
48       implemented as macros that expand to text containing '{' and  '}',  re‐
49       spectively.   For  this  reason,  the  caller must ensure that calls to
50       these functions are paired within the same function, and  at  the  same
51       lexical  nesting  level.  (In other words, a clean-up handler is estab‐
52       lished only during the execution of a specified section of code.)
53
54       Calling longjmp(3) (siglongjmp(3)) produces undefined  results  if  any
55       call  has  been made to pthread_cleanup_push() or pthread_cleanup_pop()
56       without the matching call of the pair since the jump buffer was  filled
57       by   setjmp(3)  (sigsetjmp(3)).   Likewise,  calling  longjmp(3)  (sig‐
58       longjmp(3)) from inside a clean-up handler produces  undefined  results
59       unless  the jump buffer was also filled by setjmp(3) (sigsetjmp(3)) in‐
60       side the handler.
61

RETURN VALUE

63       These functions do not return a value.
64

ERRORS

66       There are no errors.
67

ATTRIBUTES

69       For an  explanation  of  the  terms  used  in  this  section,  see  at‐
70       tributes(7).
71
72       ┌────────────────────────────────────────────┬───────────────┬─────────┐
73Interface                                   Attribute     Value   
74       ├────────────────────────────────────────────┼───────────────┼─────────┤
75pthread_cleanup_push(),                     │ Thread safety │ MT-Safe │
76pthread_cleanup_pop()                       │               │         │
77       └────────────────────────────────────────────┴───────────────┴─────────┘
78

CONFORMING TO

80       POSIX.1-2001, POSIX.1-2008.
81

NOTES

83       On Linux, the pthread_cleanup_push()  and  pthread_cleanup_pop()  func‐
84       tions  are implemented as macros that expand to text containing '{' and
85       '}', respectively.  This means that variables declared within the scope
86       of  paired  calls  to  these functions will be visible within only that
87       scope.
88
89       POSIX.1 says that the effect of using return, break, continue, or  goto
90       to  prematurely  leave  a  block  bracketed  pthread_cleanup_push() and
91       pthread_cleanup_pop() is undefined.  Portable applications should avoid
92       doing this.
93

EXAMPLES

95       The program below provides a simple example of the use of the functions
96       described in this page.  The program creates a thread that  executes  a
97       loop  bracketed  by  pthread_cleanup_push()  and pthread_cleanup_pop().
98       This loop increments a global variable, cnt, once each second.  Depend‐
99       ing  on what command-line arguments are supplied, the main thread sends
100       the other thread a cancellation request, or sets a global variable that
101       causes the other thread to exit its loop and terminate normally (by do‐
102       ing a return).
103
104       In the following shell session, the main thread  sends  a  cancellation
105       request to the other thread:
106
107           $ ./a.out
108           New thread started
109           cnt = 0
110           cnt = 1
111           Canceling thread
112           Called clean-up handler
113           Thread was canceled; cnt = 0
114
115       From  the above, we see that the thread was canceled, and that the can‐
116       cellation clean-up handler was called and it reset  the  value  of  the
117       global variable cnt to 0.
118
119       In  the  next  run, the main program sets a global variable that causes
120       other thread to terminate normally:
121
122           $ ./a.out x
123           New thread started
124           cnt = 0
125           cnt = 1
126           Thread terminated normally; cnt = 2
127
128       From the above, we see that the clean-up handler was not executed  (be‐
129       cause  cleanup_pop_arg  was  0), and therefore the value of cnt was not
130       reset.
131
132       In the next run, the main program sets a global  variable  that  causes
133       the  other  thread  to terminate normally, and supplies a nonzero value
134       for cleanup_pop_arg:
135
136           $ ./a.out x 1
137           New thread started
138           cnt = 0
139           cnt = 1
140           Called clean-up handler
141           Thread terminated normally; cnt = 0
142
143       In the above, we see that although the thread  was  not  canceled,  the
144       clean-up   handler   was   executed,  because  the  argument  given  to
145       pthread_cleanup_pop() was nonzero.
146
147   Program source
148
149       #include <pthread.h>
150       #include <sys/types.h>
151       #include <stdio.h>
152       #include <stdlib.h>
153       #include <unistd.h>
154       #include <errno.h>
155
156       #define handle_error_en(en, msg) \
157               do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
158
159       static int done = 0;
160       static int cleanup_pop_arg = 0;
161       static int cnt = 0;
162
163       static void
164       cleanup_handler(void *arg)
165       {
166           printf("Called clean-up handler\n");
167           cnt = 0;
168       }
169
170       static void *
171       thread_start(void *arg)
172       {
173           time_t start, curr;
174
175           printf("New thread started\n");
176
177           pthread_cleanup_push(cleanup_handler, NULL);
178
179           curr = start = time(NULL);
180
181           while (!done) {
182               pthread_testcancel();           /* A cancellation point */
183               if (curr < time(NULL)) {
184                   curr = time(NULL);
185                   printf("cnt = %d\n", cnt);  /* A cancellation point */
186                   cnt++;
187               }
188           }
189
190           pthread_cleanup_pop(cleanup_pop_arg);
191           return NULL;
192       }
193
194       int
195       main(int argc, char *argv[])
196       {
197           pthread_t thr;
198           int s;
199           void *res;
200
201           s = pthread_create(&thr, NULL, thread_start, NULL);
202           if (s != 0)
203               handle_error_en(s, "pthread_create");
204
205           sleep(2);           /* Allow new thread to run a while */
206
207           if (argc > 1) {
208               if (argc > 2)
209                   cleanup_pop_arg = atoi(argv[2]);
210               done = 1;
211
212           } else {
213               printf("Canceling thread\n");
214               s = pthread_cancel(thr);
215               if (s != 0)
216                   handle_error_en(s, "pthread_cancel");
217           }
218
219           s = pthread_join(thr, &res);
220           if (s != 0)
221               handle_error_en(s, "pthread_join");
222
223           if (res == PTHREAD_CANCELED)
224               printf("Thread was canceled; cnt = %d\n", cnt);
225           else
226               printf("Thread terminated normally; cnt = %d\n", cnt);
227           exit(EXIT_SUCCESS);
228       }
229

SEE ALSO

231       pthread_cancel(3), pthread_cleanup_push_defer_np(3), pthread_setcancel‐
232       state(3), pthread_testcancel(3), pthreads(7)
233

COLOPHON

235       This  page  is  part of release 5.13 of the Linux man-pages project.  A
236       description of the project, information about reporting bugs,  and  the
237       latest     version     of     this    page,    can    be    found    at
238       https://www.kernel.org/doc/man-pages/.
239
240
241
242Linux                             2021-03-22           PTHREAD_CLEANUP_PUSH(3)
Impressum