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 *),
13                                 void *arg);
14       void pthread_cleanup_pop(int execute);
15
16       Compile and link with -pthread.
17

DESCRIPTION

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

RETURN VALUE

64       These functions do not return a value.
65

ERRORS

67       There are no errors.
68

CONFORMING TO

70       POSIX.1-2001.
71

NOTES

73       On Linux, the pthread_cleanup_push()  and  pthread_cleanup_pop()  func‐
74       tions  are implemented as macros that expand to text containing '{' and
75       '}', respectively.  This means that variables declared within the scope
76       of  paired  calls  to  these functions will only be visible within that
77       scope.
78
79       POSIX.1 says that the effect of using return, break, continue, or  goto
80       to  prematurely  leave  a  block  bracketed  pthread_cleanup_push() and
81       pthread_cleanup_pop() is undefined.  Portable applications should avoid
82       doing this.
83

EXAMPLE

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

SEE ALSO

221       pthread_cancel(3), pthread_cleanup_push_defer_np(3), pthread_setcancel‐
222       state(3), pthread_testcancel(3), pthreads(7)
223

COLOPHON

225       This  page  is  part of release 3.25 of the Linux man-pages project.  A
226       description of the project, and information about reporting  bugs,  can
227       be found at http://www.kernel.org/doc/man-pages/.
228
229
230
231Linux                             2008-11-24           PTHREAD_CLEANUP_PUSH(3)
Impressum