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