/******************************************************** * An example source module to accompany... * * "Using POSIX Threads: Programming with Pthreads" * by Brad nichols, Dick Buttlar, Jackie Farrell * O'Reilly & Associates, Inc. * ******************************************************** * async_safe -- * * Example showing macro wrappers for calling non-async * safe routines when the caller has asynchronous * cancellation turned on */ #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #include <pthread.h> #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(); \ } #define async_cancel_safe_write(fd,buf,amt) \ { \ int oldtype; \ pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype); \ if (write(fd,buf,amt) < 0) \ perror("write"), exit(1); \ pthread_setcanceltype(oldtype,NULL); \ pthread_testcancel(); \ } static int fd; void *io(void *arg) { int *fd2=(int *)arg; char buf[20]="String"; int amt=20; for (;;) { async_cancel_safe_write(*fd2,buf,amt); async_cancel_safe_read(*fd2,buf,amt); } return(NULL); } void *killer(void *arg) { pthread_t * target = (pthread_t *)arg; sleep(1); pthread_cancel(*target); return(NULL); } extern int main(void) { pthread_t io_thread, killer_thread; // extern void *io(void *); // extern void *killer(void *); if ((fd = open(".ktemp",O_CREAT | O_RDWR, 0666)) < 0) perror("open"), exit(1); pthread_create(&io_thread, NULL, io, (void *)&fd); pthread_create(&killer_thread, NULL, killer, (void *)&io_thread); pthread_join(io_thread, NULL); pthread_join(killer_thread,NULL); if ((close(fd)) < 0) perror("close"),exit(1); if ((unlink(".ktemp")) < 0) perror("unlink"),exit(1); return 0; }