OSDN Git Service

Import translated manuals from JM CVS Repository.
[linuxjm/jm.git] / manual / glibc-linuxthreads / original / man3 / pthread_cleanup_push.3
1 .TH PTHREAD_CLEANUP 3 LinuxThreads
2
3
4 .SH NAME
5 pthread_cleanup_push, pthread_cleanup_pop, pthread_cleanup_push_defer_np, pthread_cleanup_pop_restore_np \- install and remove cleanup handlers
6
7 .SH SYNOPSIS
8 .B #include <pthread.h>
9
10 .BI "void pthread_cleanup_push(void (*" routine ") (void *), void *" arg ");"
11
12 .BI "void pthread_cleanup_pop(int " execute ");"
13
14 .BI "void pthread_cleanup_push_defer_np(void (*" routine ") (void *), void *" arg ");"
15
16 .BI "void pthread_cleanup_pop_restore_np(int " execute ");"
17
18 .SH DESCRIPTION
19
20 Cleanup handlers are functions that get called when a thread
21 terminates, either by calling 
22 .BR "pthread_exit" (3)
23 or because of
24 cancellation. Cleanup handlers are installed and removed following a
25 stack-like discipline.
26
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
34 with 
35 .BR "malloc" (3)
36 or close file descriptors on thread termination.
37
38 .B "pthread_cleanup_push"
39 installs the 
40 .I "routine"
41 function with argument
42 .I "arg"
43 as a cleanup handler. From this point on to the matching
44 .BR "pthread_cleanup_pop" ,
45 the function 
46 .I "routine"
47 will be called with
48 arguments 
49 .I "arg"
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.
55
56 .B "pthread_cleanup_pop"
57 removes the most recently installed cleanup
58 handler. If the 
59 .I "execute"
60 argument is not 0, it also executes the
61 handler, by calling the 
62 .I "routine"
63 function with arguments 
64 .IR "arg" .
65 If
66 the 
67 .I "execute"
68 argument is 0, the handler is only removed but not
69 executed.
70
71 Matching pairs of 
72 .B "pthread_cleanup_push"
73 and 
74 .B "pthread_cleanup_pop"
75 must occur in the same function, at the same level of block nesting.
76 Actually, 
77 .B "pthread_cleanup_push"
78 and 
79 .B "pthread_cleanup_pop"
80 are macros,
81 and the expansion of 
82 .B "pthread_cleanup_push"
83 introduces an open brace 
84 .B "{"
85 with the matching closing brace 
86 .B "}"
87 being introduced by the expansion
88 of the matching 
89 .BR "pthread_cleanup_pop" .
90
91 .B "pthread_cleanup_push_defer_np"
92 is a non-portable extension that
93 combines 
94 .B "pthread_cleanup_push"
95 and 
96 .BR "pthread_setcanceltype" (3).
97 It pushes a cleanup handler just as 
98 .B "pthread_cleanup_push"
99 does, but
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.
103
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"
110 was called.
111
112 .B "pthread_cleanup_push_defer_np"
113 and 
114 .B "pthread_cleanup_pop_restore_np"
115 must occur in matching pairs, at the same level of block nesting.
116
117 The following sequence
118
119 .RS
120 .ft 3
121 .nf
122 .sp
123 pthread_cleanup_push_defer_np(routine, arg);
124 ...
125 pthread_cleanup_pop_defer_np(execute);
126 .ft
127 .LP
128 .RE
129 .fi
130
131 is functionally equivalent to (but more compact and more efficient than)
132
133 .RS
134 .ft 3
135 .nf
136 .sp
137 { int oldtype;
138   pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype);
139   pthread_cleanup_push(routine, arg);
140   ...
141   pthread_cleanup_pop(execute);
142   pthread_setcanceltype(oldtype, NULL);
143 }
144 .ft
145 .LP
146 .RE
147 .fi
148
149 .SH "RETURN VALUE"
150
151 None.
152
153 .SH ERRORS
154
155 None.
156
157 .SH AUTHOR
158 Xavier Leroy <Xavier.Leroy@inria.fr>
159
160 .SH "SEE ALSO"
161 .BR "pthread_exit" (3),
162 .BR "pthread_cancel" (3),
163 .BR "pthread_setcanceltype" (3).
164
165 .SH EXAMPLE
166
167 Here is how to lock a mutex 
168 .I "mut"
169 in such a way that it will be
170 unlocked if the thread is canceled while 
171 .I "mut"
172 is locked:
173
174 .RS
175 .ft 3
176 .nf
177 .sp
178 pthread_cleanup_push(pthread_mutex_unlock, (void *) &mut);
179 pthread_mutex_lock(&mut);
180 /* do some work */
181 pthread_mutex_unlock(&mut);
182 pthread_cleanup_pop(0);
183 .ft
184 .LP
185 .RE
186 .fi
187
188 Equivalently, the last two lines can be replaced by
189
190 .RS
191 .ft 3
192 .nf
193 .sp
194 pthread_cleanup_pop(1);
195 .ft
196 .LP
197 .RE
198 .fi
199
200 Notice that the code above is safe only in deferred cancellation mode
201 (see 
202 .BR "pthread_setcanceltype" (3)).
203 In asynchronous cancellation mode,
204 a cancellation can occur between 
205 .B "pthread_cleanup_push"
206 and
207 .BR "pthread_mutex_lock" ,
208 or between 
209 .B "pthread_mutex_unlock"
210 and
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.
215
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
218 mutex:
219
220 .RS
221 .ft 3
222 .nf
223 .sp
224 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype);
225 pthread_cleanup_push(pthread_mutex_unlock, (void *) &mut);
226 pthread_mutex_lock(&mut);
227 /* do some work */
228 pthread_cleanup_pop(1);
229 pthread_setcanceltype(oldtype, NULL);
230 .ft
231 .LP
232 .RE
233 .fi
234
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"
238 and 
239 .BR "pthread_cleanup_pop_restore_np" :
240
241 .RS
242 .ft 3
243 .nf
244 .sp
245 pthread_cleanup_push_restore_np(pthread_mutex_unlock, (void *) &mut);
246 pthread_mutex_lock(&mut);
247 /* do some work */
248 pthread_cleanup_pop_restore_np(1);
249 .ft
250 .LP
251 .RE
252 .fi
253