32
32
normally. The best way to avoid this is, just before locking the
33
33
mutex, to install a cleanup handler whose effect is to unlock the
34
34
mutex. Cleanup handlers can be used similarly to free blocks allocated
35
with !malloc!(3) or close file descriptors on thread termination.
35
with \fBmalloc\fP(3) or close file descriptors on thread termination.
37
!pthread_cleanup_push! installs the |routine| function with argument
38
|arg| as a cleanup handler. From this point on to the matching
39
!pthread_cleanup_pop!, the function |routine| will be called with
40
arguments |arg| when the thread terminates, either through !pthread_exit!(3)
37
\fBpthread_cleanup_push\fP installs the \fIroutine\fP function with argument
38
\fIarg\fP as a cleanup handler. From this point on to the matching
39
\fBpthread_cleanup_pop\fP, the function \fIroutine\fP will be called with
40
arguments \fIarg\fP when the thread terminates, either through \fBpthread_exit\fP(3)
41
41
or by cancellation. If several cleanup handlers are active at that
42
42
point, they are called in LIFO order: the most recently installed
43
43
handler is called first.
45
!pthread_cleanup_pop! removes the most recently installed cleanup
46
handler. If the |execute| argument is not 0, it also executes the
47
handler, by calling the |routine| function with arguments |arg|. If
48
the |execute| argument is 0, the handler is only removed but not
45
\fBpthread_cleanup_pop\fP removes the most recently installed cleanup
46
handler. If the \fIexecute\fP argument is not 0, it also executes the
47
handler, by calling the \fIroutine\fP function with arguments \fIarg\fP. If
48
the \fIexecute\fP argument is 0, the handler is only removed but not
51
Matching pairs of !pthread_cleanup_push! and !pthread_cleanup_pop!
51
Matching pairs of \fBpthread_cleanup_push\fP and \fBpthread_cleanup_pop\fP
52
52
must occur in the same function, at the same level of block nesting.
53
Actually, !pthread_cleanup_push! and !pthread_cleanup_pop! are macros,
54
and the expansion of !pthread_cleanup_push! introduces an open brace !{!
55
with the matching closing brace !}! being introduced by the expansion
56
of the matching !pthread_cleanup_pop!.
53
Actually, \fBpthread_cleanup_push\fP and \fBpthread_cleanup_pop\fP are macros,
54
and the expansion of \fBpthread_cleanup_push\fP introduces an open brace \fB{\fP
55
with the matching closing brace \fB}\fP being introduced by the expansion
56
of the matching \fBpthread_cleanup_pop\fP.
58
!pthread_cleanup_push_defer_np! is a non-portable extension that
59
combines !pthread_cleanup_push! and !pthread_setcanceltype!(3).
60
It pushes a cleanup handler just as !pthread_cleanup_push! does, but
58
\fBpthread_cleanup_push_defer_np\fP is a non-portable extension that
59
combines \fBpthread_cleanup_push\fP and \fBpthread_setcanceltype\fP(3).
60
It pushes a cleanup handler just as \fBpthread_cleanup_push\fP does, but
61
61
also saves the current cancellation type and sets it to deferred
62
62
cancellation. This ensures that the cleanup mechanism is effective
63
63
even if the thread was initially in asynchronous cancellation mode.
65
!pthread_cleanup_pop_restore_np! pops a cleanup handler introduced by
66
!pthread_cleanup_push_defer_np!, and restores the cancellation type to
67
its value at the time !pthread_cleanup_push_defer_np! was called.
65
\fBpthread_cleanup_pop_restore_np\fP pops a cleanup handler introduced by
66
\fBpthread_cleanup_push_defer_np\fP, and restores the cancellation type to
67
its value at the time \fBpthread_cleanup_push_defer_np\fP was called.
69
!pthread_cleanup_push_defer_np! and !pthread_cleanup_pop_restore_np!
69
\fBpthread_cleanup_push_defer_np\fP and \fBpthread_cleanup_pop_restore_np\fP
70
70
must occur in matching pairs, at the same level of block nesting.
72
72
The following sequence
151
151
Notice that the code above is safe only in deferred cancellation mode
152
(see !pthread_setcanceltype!(3)). In asynchronous cancellation mode,
153
a cancellation can occur between !pthread_cleanup_push! and
154
!pthread_mutex_lock!, or between !pthread_mutex_unlock! and
155
!pthread_cleanup_pop!, resulting in both cases in the thread trying to
152
(see \fBpthread_setcanceltype\fP(3)). In asynchronous cancellation mode,
153
a cancellation can occur between \fBpthread_cleanup_push\fP and
154
\fBpthread_mutex_lock\fP, or between \fBpthread_mutex_unlock\fP and
155
\fBpthread_cleanup_pop\fP, resulting in both cases in the thread trying to
156
156
unlock a mutex not locked by the current thread. This is the main
157
157
reason why asynchronous cancellation is difficult to use.