1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/******************************************************** 2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * An example source module to accompany... 3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * 4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * "Using POSIX Threads: Programming with Pthreads" 5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * by Brad nichols, Dick Buttlar, Jackie Farrell 6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * O'Reilly & Associates, Inc. 7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * 8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ******************************************************** 9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * async_safe -- 10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * 11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Example showing macro wrappers for calling non-async 12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * safe routines when the caller has asynchronous 13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * cancellation turned on 14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdlib.h> 17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdio.h> 18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <unistd.h> 19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <fcntl.h> 20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <sys/types.h> 21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <sys/stat.h> 22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <pthread.h> 24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define async_cancel_safe_read(fd,buf,amt) \ 27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { \ 28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int oldtype; \ 29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype); \ 30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (read(fd,buf,amt) < 0) \ 31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown perror("read"),exit(1); \ 32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_setcanceltype(oldtype,NULL); \ 33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_testcancel(); \ 34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define async_cancel_safe_write(fd,buf,amt) \ 38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { \ 39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int oldtype; \ 40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype); \ 41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (write(fd,buf,amt) < 0) \ 42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown perror("write"), exit(1); \ 43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_setcanceltype(oldtype,NULL); \ 44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_testcancel(); \ 45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int fd; 49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid *io(void *arg) 51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int *fd2=(int *)arg; 53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown char buf[20]="String"; 54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int amt=20; 55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (;;) { 57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown async_cancel_safe_write(*fd2,buf,amt); 58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown async_cancel_safe_read(*fd2,buf,amt); 59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return(NULL); 61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid *killer(void *arg) 64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_t * target = (pthread_t *)arg; 66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sleep(1); 67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_cancel(*target); 68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return(NULL); 69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern int 72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmain(void) 73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_t io_thread, killer_thread; 75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // extern void *io(void *); 77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // extern void *killer(void *); 78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ((fd = open(".ktemp",O_CREAT | O_RDWR, 0666)) < 0) 80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown perror("open"), exit(1); 81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_create(&io_thread, 83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown NULL, 84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown io, 85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (void *)&fd); 86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_create(&killer_thread, 87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown NULL, 88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown killer, 89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (void *)&io_thread); 90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_join(io_thread, NULL); 92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_join(killer_thread,NULL); 94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ((close(fd)) < 0) 96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown perror("close"),exit(1); 97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ((unlink(".ktemp")) < 0) 98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown perror("unlink"),exit(1); 99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 0; 101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 102