Add Book to My BookshelfPurchase This Book Online

Chapter 5 - Pthreads and UNIX

Pthreads Programming
Bradford Nichols, Dick Buttlar and Jacqueline Proulx Farrell
 Copyright 1996 O'Reilly & Associates, Inc.

Cancellation-Safe Library Functions and System Calls
Using thread cancellation can have a number of pitfalls, not the least of which is the accidental cancellation of a thread that holds a lock or that has just allocated some memory. We helped you safeguard your code against such disasters in Chapter 4, Managing Pthreads. Now we'll take some time to acquaint you with what Pthreads vendors do to ensure that their libraries continue to work as expected when confronted with cancellation in a multithreaded environment. 
When you call library functions from a program that uses thread cancellation, you must consider two important questions: 
 Can the thread be safely canceled while it's executing in these functions? 
 Do any of these functions act as cancellation points for a deferred cancellation? 
Asynchronous Cancellation-Safe Functions
Remember that, when asynchronous cancellation is enabled for a thread, any pthread_cancel call aimed at it will terminate the thread immediately, no matter what it's doing. It's up to you to ensure that a routine running under the threat of thread cancellation doesn't hold locks or have resources allocated. When a routine is designed in this way, it's known as an asynchronous cancellation-safe function
As we've seen, system libraries were originally written without consideration of threads. Although the Pthreads standard requires vendors to make most POSIX.1 function calls threadsafe (and defines various workarounds for the others), it doesn't force them to make POSIX.1 libraries (or ANSI C or vendor-specific libraries) asynchronous cancellation-safe. This means if a thread is canceled in the middle of a library call, it may terminate while library data is in an inconsistent state or while the library holds memory allocated on the thread's behalf. As a result, when using asynchronous cancellation in a multithreaded program, you should call only those library functions that are documented as being asynchronous cancellation-safe. Very few are. 
Nevertheless, if your program truly needs the functionality that these asynchronous cancellation-unsafe functions provide, you can dodge potential problems by resetting the thread's cancelability type to deferred for the duration of the function call. Defining a wrapper macro, as shown in Example 5-8, should do the trick. 
Example 5-8: An Asynchronous Cancellation Wrapper Macro (async_safe.c)
#define async_cancel_safe_read(fd, buf, amt) \
   {\
int oldtype; \
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype); \
if (read(fd, buf, amt) < 0) \
perror("read"), exit(-1); \
pthread_setcanceltype(oldtype, NULL); \
pthread_testcancel(); \
   }
A thread invokes the async_cancel_safe_read macro instead of calling read directly. The macro first enables deferred cancellation with a pthread_setcanceltype call, which sets things up so that while the thread is in the read call any cancellations delivered to it will be made pending. When the read call returns, the macro makes a pthread_testcancel call, forcing any pending cancellations to be delivered. If this is not the case, the macro proceeds to the next line, a pthread_setcanceltype call that sets the thread's cancelability type back to asynchronous. 
Cancellation Points in System and Library Calls
Let's review what we know about cancellation points. 
When deferred cancellation is enabled for a thread, it can be terminated only at defined cancellation points. Thus far, we know of four Pthreads function calls that act as cancellation points: they are pthread_testcancel, pthread_cond_wait, pthread_cond_timedwait, and pthread_join. The pthread_testcancel function allows you to insert an explicit cancellation point in a thread. Because the other functions can cause a calling thread to block for a long time, they force a thread's termination if its cancellation is pending at the time of the call. 
It would be useful if other system and library calls that impose long waits on their callers could also act as cancellation points. In fact, the Pthreads standard lists over fifty POSIX.1 and ANSI C routines that vendors may define as cancellation points: 
closedir
ctermid
fclose
fcntl
fflush
fgetc
fgets
fopen
fprintf
fputc
fputs
fread
freopen
fscanf
fseek
ftell
fwrite
getc
getchar
getchar_unlocked
getc_unlocked
getcwd
getgrgid
getgrgid_r
getgrnam
getgrnam_r
getlogin
getlogin_r
getpwnam
getpwnam_r
getpwuid
getpwuid_r
gets
lseek
opendir
perror
printf
putc
putchar
putchar_unlocked
putc_unlocked
puts
readdir
remove
rename
rewind
rewinddir
scanf
tmpfile
tmpname
ttyname
ttyname_r
ungetc
unlink
The following routines must be defined as cancellation points on all implementations: 
aio_suspend
close
creat
fcntl
fsync
mg_receive
mg_send
msync
nanosleep
open
pause
read
sem_wait
sigsuspend
sigtimedwait
sigwait
sigwaitinfo
sleep
system
tcdrain
wait
waitpid
write

Previous SectionNext Section
Books24x7.com, Inc 2000   Feedback