diff options
Diffstat (limited to 'usr/src/man/man7/cancellation.7')
| -rw-r--r-- | usr/src/man/man7/cancellation.7 | 438 |
1 files changed, 438 insertions, 0 deletions
diff --git a/usr/src/man/man7/cancellation.7 b/usr/src/man/man7/cancellation.7 new file mode 100644 index 0000000000..4b3362127b --- /dev/null +++ b/usr/src/man/man7/cancellation.7 @@ -0,0 +1,438 @@ +.\" +.\" Sun Microsystems, Inc. gratefully acknowledges The Open Group for +.\" permission to reproduce portions of its copyrighted documentation. +.\" Original documentation from The Open Group can be obtained online at +.\" http://www.opengroup.org/bookstore/. +.\" +.\" The Institute of Electrical and Electronics Engineers and The Open +.\" Group, have given us permission to reprint portions of their +.\" documentation. +.\" +.\" In the following statement, the phrase ``this text'' refers to portions +.\" of the system documentation. +.\" +.\" Portions of this text are reprinted and reproduced in electronic form +.\" in the SunOS Reference Manual, from IEEE Std 1003.1, 2004 Edition, +.\" Standard for Information Technology -- Portable Operating System +.\" Interface (POSIX), The Open Group Base Specifications Issue 6, +.\" Copyright (C) 2001-2004 by the Institute of Electrical and Electronics +.\" Engineers, Inc and The Open Group. In the event of any discrepancy +.\" between these versions and the original IEEE and The Open Group +.\" Standard, the original IEEE and The Open Group Standard is the referee +.\" document. The original Standard can be obtained online at +.\" http://www.opengroup.org/unix/online.html. +.\" +.\" This notice shall appear on any product containing this material. +.\" +.\" The contents of this file are subject to the terms of the +.\" Common Development and Distribution License (the "License"). +.\" You may not use this file except in compliance with the License. +.\" +.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +.\" or http://www.opensolaris.org/os/licensing. +.\" See the License for the specific language governing permissions +.\" and limitations under the License. +.\" +.\" When distributing Covered Code, include this CDDL HEADER in each +.\" file and include the License file at usr/src/OPENSOLARIS.LICENSE. +.\" If applicable, add the following below this CDDL HEADER, with the +.\" fields enclosed by brackets "[]" replaced with your own identifying +.\" information: Portions Copyright [yyyy] [name of copyright owner] +.\" +.\" +.\" Portions Copyright (c) 1995 IEEE. All Rights Reserved. +.\" Copyright (c) 2001, The IEEE and The Open Group. All Rights Reserved. +.\" Copyright (c) 2008, Sun Microsystems, Inc. All Rights Reserved. +.\" +.TH CANCELLATION 7 "Oct 4, 2005" +.SH NAME +cancellation \- overview of concepts related to POSIX thread cancellation +.SH DESCRIPTION +.TS +box; +c | c +l | l . +FUNCTION ACTION +_ +\fBpthread_cancel()\fR Cancels thread execution. +\fBpthread_setcancelstate()\fR Sets the cancellation \fIstate\fR of a thread. +\fBpthread_setcanceltype()\fR Sets the cancellation \fItype\fR of a thread. +\fBpthread_testcancel()\fR T{ +Creates a cancellation point in the calling thread. +T} +\fBpthread_cleanup_push()\fR Pushes a cleanup handler routine. +\fBpthread_cleanup_pop()\fR Pops a cleanup handler routine. +.TE + +.SS "Cancellation" +.LP +Thread cancellation allows a thread to terminate the execution of any +application thread in the process. Cancellation is useful when further +operations of one or more threads are undesirable or unnecessary. +.sp +.LP +An example of a situation that could benefit from using cancellation is an +asynchronously-generated cancel condition such as a user requesting to close or +exit some running operation. Another example is the completion of a task +undertaken by a number of threads, such as solving a maze. While many threads +search for the solution, one of the threads might solve the puzzle while the +others continue to operate. Since they are serving no purpose at that point, +they should all be canceled. +.SS "Planning Steps" +.LP +Planning and programming for most cancellations follow this pattern: +.RS +4 +.TP +1. +Identify which threads you want to cancel, and insert +\fBpthread_cancel\fR(3C) statements. +.RE +.RS +4 +.TP +2. +Identify system-defined cancellation points where a thread that might be +canceled could have changed system or program state that should be restored. +See the \fBCancellation Points\fR for a list. +.RE +.RS +4 +.TP +3. +When a thread changes the system or program state just before a cancellation +point, and should restore that state before the thread is canceled, place a +cleanup handler before the cancellation point with +\fBpthread_cleanup_push\fR(3C). Wherever a thread restores the changed state, +pop the cleanup handler from the cleanup stack with +\fBpthread_cleanup_pop\fR(3C). +.RE +.RS +4 +.TP +4. +Know whether the threads you are canceling call into cancel-unsafe +libraries, and disable cancellation with \fBpthread_setcancelstate\fR(3C) +before the call into the library. See \fBCancellation State\fR and +\fBCancel-Safe\fR. +.RE +.RS +4 +.TP +5. +To cancel a thread in a procedure that contains no cancellation points, +insert your own cancellation points with \fBpthread_testcancel\fR(3C). This +function creates cancellation points by testing for pending cancellations and +performing those cancellations if they are found. Push and pop cleanup handlers +around the cancellation point, if necessary (see Step 3, above). +.RE +.SS "Cancellation Points" +.LP +The system defines certain points at which cancellation can occur (cancellation +points), and you can create additional cancellation points in your application +with \fBpthread_testcancel()\fR. +.sp +.LP +The following cancellation points are defined by the system (system-defined +cancellation points): \fBcreat\fR(2), \fBaio_suspend\fR(3C), \fBclose\fR(2), +\fBcreat\fR(2), \fBgetmsg\fR(2), \fBgetpmsg\fR(2), \fBlockf\fR(3C), +\fBmq_receive\fR(3C), \fBmq_send\fR(3C), \fBmsgrcv\fR(2), \fBmsgsnd\fR(2), +\fBmsync\fR(3C), \fBnanosleep\fR(3C), \fBopen\fR(2), \fBpause\fR(2), +\fBpoll\fR(2), \fBpread\fR(2), \fBpthread_cond_timedwait\fR(3C), +\fBpthread_cond_wait\fR(3C), \fBpthread_join\fR(3C), +\fBpthread_testcancel\fR(3C), \fBputmsg\fR(2), \fBputpmsg\fR(2), +\fBpwrite\fR(2), \fBread\fR(2), \fBreadv\fR(2), \fBselect\fR(3C), +\fBsem_wait\fR(3C), \fBsigpause\fR(3C), \fBsigwaitinfo\fR(3C), +\fBsigsuspend\fR(2), \fBsigtimedwait\fR(3C), \fBsigwait\fR(2), \fBsleep\fR(3C), +\fBsync\fR(2), \fBsystem\fR(3C), \fBtcdrain\fR(3C), \fBusleep\fR(3C), +\fBwait\fR(3C), \fBwaitid\fR(2), \fBwait3\fR(3C), \fBwaitpid\fR(3C), +\fBwrite\fR(2), \fBwritev\fR(2), and \fBfcntl\fR(2), when specifying +\fBF_SETLKW\fR as the command. +.sp +.LP +When cancellation is asynchronous, cancellation can occur at any time (before, +during, or after the execution of the function defined as the cancellation +point). When cancellation is deferred (the default case), cancellation occurs +only within the scope of a function defined as a cancellation point (after the +function is called and before the function returns). See \fBCancellation +Type\fR for more information about deferred and asynchronous cancellation. +.sp +.LP +Choosing where to place cancellation points and understanding how cancellation +affects your program depend upon your understanding of both your application +and of cancellation mechanics. +.sp +.LP +Typically, any call that might require a long wait should be a cancellation +point. Operations need to check for pending cancellation requests when the +operation is about to block indefinitely. This includes threads waiting in +\fBpthread_cond_wait()\fR and \fBpthread_cond_timedwait()\fR, threads waiting +for the termination of another thread in \fBpthread_join()\fR, and threads +blocked on \fBsigwait()\fR. +.sp +.LP +A mutex is explicitly not a cancellation point and should be held for only the +minimal essential time. +.sp +.LP +Most of the dangers in performing cancellations deal with properly restoring +invariants and freeing shared resources. For example, a carelessly canceled +thread might leave a mutex in a locked state, leading to a deadlock. Or it +might leave a region of memory allocated with no way to identify it and +therefore no way to free it. +.SS "Cleanup Handlers" +.LP +When a thread is canceled, it should release resources and clean up the state +that is shared with other threads. So, whenever a thread that might be canceled +changes the state of the system or of the program, be sure to push a cleanup +handler with \fBpthread_cleanup_push\fR(3C) before the cancellation point. +.sp +.LP +When a thread is canceled, all the currently-stacked cleanup handlers are +executed in last-in-first-out (LIFO) order. Each handler is run in the scope in +which it was pushed. When the last cleanup handler returns, the thread-specific +data destructor functions are called. Thread execution terminates when the last +destructor function returns. +.sp +.LP +When, in the normal course of the program, an uncanceled thread restores state +that it had previously changed, be sure to pop the cleanup handler (that you +had set up where the change took place) using \fBpthread_cleanup_pop\fR(3C). +That way, if the thread is canceled later, only currently-changed state will be +restored by the handlers that are left in the stack. +.sp +.LP +The \fBpthread_cleanup_push()\fR and \fBpthread_cleanup_pop()\fR functions can +be implemented as macros. The application must ensure that they appear as +statements, and in pairs within the same lexical scope (that is, the +\fBpthread_cleanup_push()\fR macro can be thought to expand to a token list +whose first token is '{' with \fBpthread_cleanup_pop()\fR expanding to a token +list whose last token is the corresponding '}'). +.sp +.LP +The effect of the use of \fBreturn\fR, \fBbreak\fR, \fBcontinue\fR, and +\fBgoto\fR to prematurely leave a code block described by a pair of +\fBpthread_cleanup_push()\fR and \fBpthread_cleanup_pop()\fR function calls is +undefined. +.SS "Cancellation State" +.LP +Most programmers will use only the default cancellation state of +\fBPTHREAD_CANCEL_ENABLE\fR, but can choose to change the state by using +\fBpthread_setcancelstate\fR(3C), which determines whether a thread is +cancelable at all. With the default \fIstate\fR of +\fBPTHREAD_CANCEL_ENABLE\fR, cancellation is enabled and the thread is +cancelable at points determined by its cancellation \fItype\fR. See +\fBCancellation Type\fR. +.sp +.LP +If the \fIstate\fR is \fBPTHREAD_CANCEL_DISABLE\fR, cancellation is disabled, +the thread is not cancelable at any point, and all cancellation requests to it +are held pending. +.sp +.LP +You might want to disable cancellation before a call to a cancel-unsafe +library, restoring the old cancel state when the call returns from the library. +See \fBCancel-Safe\fR for explanations of cancel safety. +.SS "Cancellation Type" +.LP +A thread's cancellation \fBtype\fR is set with \fBpthread_setcanceltype\fR(3C), +and determines whether the thread can be canceled anywhere in its execution or +only at cancellation points. +.sp +.LP +With the default \fItype\fR of \fBPTHREAD_CANCEL_DEFERRED\fR, the thread is +cancelable only at cancellation points, and then only when cancellation is +enabled. +.sp +.LP +If the \fItype\fR is \fBPTHREAD_CANCEL_ASYNCHRONOUS\fR, the thread is +cancelable at any point in its execution (assuming, of course, that +cancellation is enabled). Try to limit regions of asynchronous cancellation to +sequences with no external dependencies that could result in dangling resources +or unresolved state conditions. Using asynchronous cancellation is discouraged +because of the danger involved in trying to guarantee correct cleanup handling +at absolutely every point in the program. +.sp + +.sp +.TS +box; +c | c | c +l | l | l . +Cancellation Type/State Table +Type State + Enabled (Default) Disabled +_ +Deferred (Default) T{ +Cancellation occurs when the target thread reaches a cancellation point and a cancel is pending. (Default) +T} T{ +All cancellation requests to the target thread are held pending. +T} +Asynchronous T{ +Receipt of a \fBpthread_cancel()\fR call causes immediate cancellation. +T} T{ +All cancellation requests to the target thread are held pending; as +soon as cancellation is re-enabled, pending cancellations are executed +immediately. +T} +.TE + +.SS "Cancel-Safe" +.LP +With the arrival of POSIX cancellation, the Cancel-Safe level has been added to +the list of MT-Safety levels. See \fBattributes\fR(7). An application or +library is Cancel-Safe whenever it has arranged for cleanup handlers to restore +system or program state wherever cancellation can occur. The application or +library is specifically Deferred-Cancel-Safe when it is Cancel-Safe for threads +whose cancellation type is \fBPTHREAD_CANCEL_DEFERRED\fR. See \fBCancellation +State\fR. It is specifically Asynchronous-Cancel-Safe when it is Cancel-Safe +for threads whose cancellation type is \fBPTHREAD_CANCEL_ASYNCHRONOUS\fR. +.sp +.LP +It is easier to arrange for deferred cancel safety, as this requires system and +program state protection only around cancellation points. In general, expect +that most applications and libraries are not Asynchronous-Cancel-Safe. +.SS "POSIX Threads Only" +.LP +The cancellation functions described in this manual page are available for +POSIX threads, only (the Solaris threads interfaces do not provide cancellation +functions). +.SH EXAMPLES +.LP +\fBExample 1 \fRCancellation example +.sp +.LP +The following short C++ example shows the pushing/popping of cancellation +handlers, the disabling/enabling of cancellation, the use of +\fBpthread_testcancel()\fR, and so on. The \fBfree_res()\fR cancellation +handler in this example is a dummy function that simply prints a message, but +that would free resources in a real application. The function \fBf2()\fR is +called from the main thread, and goes deep into its call stack by calling +itself recursively. + +.sp +.LP +Before \fBf2()\fR starts running, the newly created thread has probably posted +a cancellation on the main thread since the main thread calls \fBthr_yield()\fR +right after creating thread2. Because cancellation was initially disabled in +the main thread, through a call to \fBpthread_setcancelstate()\fR, the call to +\fBf2()\fR from \fBmain()\fR continues and constructs X at each recursive +call, even though the main thread has a pending cancellation. + +.sp +.LP +When \fBf2()\fR is called for the fifty-first time (when \fB"i == 50"\fR), +\fBf2()\fR enables cancellation by calling \fBpthread_setcancelstate()\fR. It +then establishes a cancellation point for itself by calling +\fBpthread_testcancel()\fR. (Because a cancellation is pending, a call to a +cancellation point such as \fBread\fR(2) or \fBwrite\fR(2) would also cancel +the caller here.) + +.sp +.LP +After the \fBmain()\fR thread is canceled at the fifty-first iteration, all the +cleanup handlers that were pushed are called in sequence; this is indicated by +the calls to \fBfree_res()\fR and the calls to the destructor for \fIX\fR. At +each level, the C++ runtime calls the destructor for \fIX\fR and then the +cancellation handler, \fBfree_res()\fR. The print messages from +\fBfree_res()\fR and \fIX\fR's destructor show the sequence of calls. + +.sp +.LP +At the end, the main thread is joined by thread2. Because the main thread was +canceled, its return status from \fBpthread_join()\fR is +\fBPTHREAD_CANCELED\fR. After the status is printed, thread2 returns, killing +the process (since it is the last thread in the process). + +.sp +.in +2 +.nf +#include <pthread.h> +#include <sched.h> +extern "C" void thr_yield(void); + +extern "C" void printf(...); + +struct X { + int x; + X(int i){x = i; printf("X(%d) constructed.\en", i);} + ~X(){ printf("X(%d) destroyed.\en", x);} +}; + +void +free_res(void *i) +{ + printf("Freeing `%d`\en",i); +} + +char* f2(int i) +{ + try { + X dummy(i); + pthread_cleanup_push(free_res, (void *)i); + if (i == 50) { + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + pthread_testcancel(); + } + f2(i+1); + pthread_cleanup_pop(0); + } + catch (int) { + printf("Error: In handler.\en"); + } + return "f2"; +} + +void * +thread2(void *tid) +{ + void *sts; + + printf("I am new thread :%d\en", pthread_self()); + + pthread_cancel((pthread_t)tid); + + pthread_join((pthread_t)tid, &sts); + + printf("main thread cancelled due to %d\en", sts); + + return (sts); +} + +main() +{ + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); + pthread_create(NULL, NULL, thread2, (void *)pthread_self()); + thr_yield(); + printf("Returned from %s\en",f2(0)); +} +.fi +.in -2 + +.SH ATTRIBUTES +.LP +See \fBattributes\fR(7) for descriptions of the following attributes: +.sp + +.sp +.TS +box; +c | c +l | l . +ATTRIBUTE TYPE ATTRIBUTE VALUE +_ +MT-Level MT-Safe +.TE + +.SH SEE ALSO +.LP +.BR read (2), +.BR sigwait (2), +.BR write (2), +.BR Intro (3), +.BR pthread_cleanup_pop (3C), +.BR pthread_cleanup_push (3C), +.BR pthread_exit (3C), +.BR pthread_join (3C), +.BR pthread_setcancelstate (3C), +.BR pthread_setcanceltype (3C), +.BR pthread_testcancel (3C), +.BR setjmp (3C), +.BR attributes (7), +.BR condition (7), +.BR standards (7) |
