1 .TH PTHREAD_CLEANUP 3 LinuxThreads
5 pthread_cleanup_push, pthread_cleanup_pop, pthread_cleanup_push_defer_np, pthread_cleanup_pop_restore_np \- install and remove cleanup handlers
8 .B #include <pthread.h>
10 .BI "void pthread_cleanup_push(void (*" routine ") (void *), void *" arg ");"
12 .BI "void pthread_cleanup_pop(int " execute ");"
14 .BI "void pthread_cleanup_push_defer_np(void (*" routine ") (void *), void *" arg ");"
16 .BI "void pthread_cleanup_pop_restore_np(int " execute ");"
20 Cleanup handlers are functions that get called when a thread
21 terminates, either by calling
22 .BR "pthread_exit" (3)
24 cancellation. Cleanup handlers are installed and removed following a
25 stack-like discipline.
27 The purpose of cleanup handlers is to free the resources that a thread
28 may hold at the time it terminates. In particular, if a thread
29 exits or is cancelled while it owns a locked mutex, the mutex will
30 remain locked forever and prevent other threads from executing
31 normally. The best way to avoid this is, just before locking the
32 mutex, to install a cleanup handler whose effect is to unlock the
33 mutex. Cleanup handlers can be used similarly to free blocks allocated
36 or close file descriptors on thread termination.
38 .B "pthread_cleanup_push"
41 function with argument
43 as a cleanup handler. From this point on to the matching
44 .BR "pthread_cleanup_pop" ,
50 when the thread terminates, either through
51 .BR "pthread_exit" (3)
52 or by cancellation. If several cleanup handlers are active at that
53 point, they are called in LIFO order: the most recently installed
54 handler is called first.
56 .B "pthread_cleanup_pop"
57 removes the most recently installed cleanup
60 argument is not 0, it also executes the
61 handler, by calling the
63 function with arguments
68 argument is 0, the handler is only removed but not
72 .B "pthread_cleanup_push"
74 .B "pthread_cleanup_pop"
75 must occur in the same function, at the same level of block nesting.
77 .B "pthread_cleanup_push"
79 .B "pthread_cleanup_pop"
82 .B "pthread_cleanup_push"
83 introduces an open brace
85 with the matching closing brace
87 being introduced by the expansion
89 .BR "pthread_cleanup_pop" .
91 .B "pthread_cleanup_push_defer_np"
92 is a non-portable extension that
94 .B "pthread_cleanup_push"
96 .BR "pthread_setcanceltype" (3).
97 It pushes a cleanup handler just as
98 .B "pthread_cleanup_push"
100 also saves the current cancellation type and sets it to deferred
101 cancellation. This ensures that the cleanup mechanism is effective
102 even if the thread was initially in asynchronous cancellation mode.
104 .B "pthread_cleanup_pop_restore_np"
105 pops a cleanup handler introduced by
106 .BR "pthread_cleanup_push_defer_np" ,
107 and restores the cancellation type to
108 its value at the time
109 .B "pthread_cleanup_push_defer_np"
112 .B "pthread_cleanup_push_defer_np"
114 .B "pthread_cleanup_pop_restore_np"
115 must occur in matching pairs, at the same level of block nesting.
117 The following sequence
123 pthread_cleanup_push_defer_np(routine, arg);
125 pthread_cleanup_pop_defer_np(execute);
131 is functionally equivalent to (but more compact and more efficient than)
138 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype);
139 pthread_cleanup_push(routine, arg);
141 pthread_cleanup_pop(execute);
142 pthread_setcanceltype(oldtype, NULL);
158 Xavier Leroy <Xavier.Leroy@inria.fr>
161 .BR "pthread_exit" (3),
162 .BR "pthread_cancel" (3),
163 .BR "pthread_setcanceltype" (3).
167 Here is how to lock a mutex
169 in such a way that it will be
170 unlocked if the thread is canceled while
178 pthread_cleanup_push(pthread_mutex_unlock, (void *) &mut);
179 pthread_mutex_lock(&mut);
181 pthread_mutex_unlock(&mut);
182 pthread_cleanup_pop(0);
188 Equivalently, the last two lines can be replaced by
194 pthread_cleanup_pop(1);
200 Notice that the code above is safe only in deferred cancellation mode
202 .BR "pthread_setcanceltype" (3)).
203 In asynchronous cancellation mode,
204 a cancellation can occur between
205 .B "pthread_cleanup_push"
207 .BR "pthread_mutex_lock" ,
209 .B "pthread_mutex_unlock"
211 .BR "pthread_cleanup_pop" ,
212 resulting in both cases in the thread trying to
213 unlock a mutex not locked by the current thread. This is the main
214 reason why asynchronous cancellation is difficult to use.
216 If the code above must also work in asynchronous cancellation mode,
217 then it must switch to deferred mode for locking and unlocking the
224 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype);
225 pthread_cleanup_push(pthread_mutex_unlock, (void *) &mut);
226 pthread_mutex_lock(&mut);
228 pthread_cleanup_pop(1);
229 pthread_setcanceltype(oldtype, NULL);
235 The code above can be rewritten in a more compact and more
236 efficient way, using the non-portable functions
237 .B "pthread_cleanup_push_defer_np"
239 .BR "pthread_cleanup_pop_restore_np" :
245 pthread_cleanup_push_restore_np(pthread_mutex_unlock, (void *) &mut);
246 pthread_mutex_lock(&mut);
248 pthread_cleanup_pop_restore_np(1);