14530f808586c19a4a6999eed07e604a456c80a3csewardj/********************************************************
24530f808586c19a4a6999eed07e604a456c80a3csewardj * An example source module to accompany...
34530f808586c19a4a6999eed07e604a456c80a3csewardj *
44530f808586c19a4a6999eed07e604a456c80a3csewardj * "Using POSIX Threads: Programming with Pthreads"
54530f808586c19a4a6999eed07e604a456c80a3csewardj *     by Brad nichols, Dick Buttlar, Jackie Farrell
64530f808586c19a4a6999eed07e604a456c80a3csewardj *     O'Reilly & Associates, Inc.
74530f808586c19a4a6999eed07e604a456c80a3csewardj *
84530f808586c19a4a6999eed07e604a456c80a3csewardj ********************************************************
94530f808586c19a4a6999eed07e604a456c80a3csewardj * async_safe --
104530f808586c19a4a6999eed07e604a456c80a3csewardj *
114530f808586c19a4a6999eed07e604a456c80a3csewardj * Example showing macro wrappers for calling non-async
124530f808586c19a4a6999eed07e604a456c80a3csewardj * safe routines when the caller has asynchronous
134530f808586c19a4a6999eed07e604a456c80a3csewardj * cancellation turned on
144530f808586c19a4a6999eed07e604a456c80a3csewardj */
154530f808586c19a4a6999eed07e604a456c80a3csewardj
164530f808586c19a4a6999eed07e604a456c80a3csewardj#include <stdlib.h>
174530f808586c19a4a6999eed07e604a456c80a3csewardj#include <stdio.h>
184530f808586c19a4a6999eed07e604a456c80a3csewardj#include <unistd.h>
194530f808586c19a4a6999eed07e604a456c80a3csewardj#include <fcntl.h>
204530f808586c19a4a6999eed07e604a456c80a3csewardj#include <sys/types.h>
214530f808586c19a4a6999eed07e604a456c80a3csewardj#include <sys/stat.h>
224530f808586c19a4a6999eed07e604a456c80a3csewardj
234530f808586c19a4a6999eed07e604a456c80a3csewardj#include <pthread.h>
244530f808586c19a4a6999eed07e604a456c80a3csewardj
254530f808586c19a4a6999eed07e604a456c80a3csewardj
264530f808586c19a4a6999eed07e604a456c80a3csewardj#define async_cancel_safe_read(fd,buf,amt) \
274530f808586c19a4a6999eed07e604a456c80a3csewardj   { \
284530f808586c19a4a6999eed07e604a456c80a3csewardj      int oldtype; \
294530f808586c19a4a6999eed07e604a456c80a3csewardj      pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype); \
304530f808586c19a4a6999eed07e604a456c80a3csewardj      if (read(fd,buf,amt) < 0) \
314530f808586c19a4a6999eed07e604a456c80a3csewardj         perror("read"),exit(1); \
324530f808586c19a4a6999eed07e604a456c80a3csewardj      pthread_setcanceltype(oldtype,NULL); \
334530f808586c19a4a6999eed07e604a456c80a3csewardj      pthread_testcancel(); \
344530f808586c19a4a6999eed07e604a456c80a3csewardj   }
354530f808586c19a4a6999eed07e604a456c80a3csewardj
364530f808586c19a4a6999eed07e604a456c80a3csewardj
374530f808586c19a4a6999eed07e604a456c80a3csewardj#define async_cancel_safe_write(fd,buf,amt) \
384530f808586c19a4a6999eed07e604a456c80a3csewardj   { \
394530f808586c19a4a6999eed07e604a456c80a3csewardj      int oldtype; \
404530f808586c19a4a6999eed07e604a456c80a3csewardj      pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype); \
414530f808586c19a4a6999eed07e604a456c80a3csewardj      if (write(fd,buf,amt) < 0) \
424530f808586c19a4a6999eed07e604a456c80a3csewardj         perror("write"), exit(1); \
434530f808586c19a4a6999eed07e604a456c80a3csewardj      pthread_setcanceltype(oldtype,NULL); \
444530f808586c19a4a6999eed07e604a456c80a3csewardj      pthread_testcancel(); \
454530f808586c19a4a6999eed07e604a456c80a3csewardj   }
464530f808586c19a4a6999eed07e604a456c80a3csewardj
474530f808586c19a4a6999eed07e604a456c80a3csewardj
484530f808586c19a4a6999eed07e604a456c80a3csewardjstatic int fd;
494530f808586c19a4a6999eed07e604a456c80a3csewardj
504530f808586c19a4a6999eed07e604a456c80a3csewardjvoid *io(void *arg)
514530f808586c19a4a6999eed07e604a456c80a3csewardj{
52e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   int *fd2=(int *)arg;
534530f808586c19a4a6999eed07e604a456c80a3csewardj   char buf[20]="String";
544530f808586c19a4a6999eed07e604a456c80a3csewardj   int amt=20;
554530f808586c19a4a6999eed07e604a456c80a3csewardj
564530f808586c19a4a6999eed07e604a456c80a3csewardj   for (;;) {
57e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn      async_cancel_safe_write(*fd2,buf,amt);
58e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn      async_cancel_safe_read(*fd2,buf,amt);
594530f808586c19a4a6999eed07e604a456c80a3csewardj   }
604530f808586c19a4a6999eed07e604a456c80a3csewardj   return(NULL);
614530f808586c19a4a6999eed07e604a456c80a3csewardj}
624530f808586c19a4a6999eed07e604a456c80a3csewardj
634530f808586c19a4a6999eed07e604a456c80a3csewardjvoid *killer(void *arg)
644530f808586c19a4a6999eed07e604a456c80a3csewardj{
654530f808586c19a4a6999eed07e604a456c80a3csewardj   pthread_t * target = (pthread_t *)arg;
664530f808586c19a4a6999eed07e604a456c80a3csewardj   sleep(1);
674530f808586c19a4a6999eed07e604a456c80a3csewardj   pthread_cancel(*target);
684530f808586c19a4a6999eed07e604a456c80a3csewardj   return(NULL);
694530f808586c19a4a6999eed07e604a456c80a3csewardj}
704530f808586c19a4a6999eed07e604a456c80a3csewardj
714530f808586c19a4a6999eed07e604a456c80a3csewardjextern int
724530f808586c19a4a6999eed07e604a456c80a3csewardjmain(void)
734530f808586c19a4a6999eed07e604a456c80a3csewardj{
744530f808586c19a4a6999eed07e604a456c80a3csewardj   pthread_t io_thread, killer_thread;
754530f808586c19a4a6999eed07e604a456c80a3csewardj
76ee588a9f45fc91767c548fb6ef22ac718077020csewardj   //   extern void *io(void *);
77ee588a9f45fc91767c548fb6ef22ac718077020csewardj   // extern void *killer(void  *);
784530f808586c19a4a6999eed07e604a456c80a3csewardj
794530f808586c19a4a6999eed07e604a456c80a3csewardj   if ((fd = open(".ktemp",O_CREAT | O_RDWR, 0666)) < 0)
804530f808586c19a4a6999eed07e604a456c80a3csewardj      perror("open"), exit(1);
814530f808586c19a4a6999eed07e604a456c80a3csewardj
824530f808586c19a4a6999eed07e604a456c80a3csewardj   pthread_create(&io_thread,
834530f808586c19a4a6999eed07e604a456c80a3csewardj		  NULL,
844530f808586c19a4a6999eed07e604a456c80a3csewardj		  io,
854530f808586c19a4a6999eed07e604a456c80a3csewardj		  (void *)&fd);
864530f808586c19a4a6999eed07e604a456c80a3csewardj   pthread_create(&killer_thread,
874530f808586c19a4a6999eed07e604a456c80a3csewardj		  NULL,
884530f808586c19a4a6999eed07e604a456c80a3csewardj		  killer,
894530f808586c19a4a6999eed07e604a456c80a3csewardj		  (void *)&io_thread);
904530f808586c19a4a6999eed07e604a456c80a3csewardj
914530f808586c19a4a6999eed07e604a456c80a3csewardj   pthread_join(io_thread, NULL);
924530f808586c19a4a6999eed07e604a456c80a3csewardj
934530f808586c19a4a6999eed07e604a456c80a3csewardj   pthread_join(killer_thread,NULL);
944530f808586c19a4a6999eed07e604a456c80a3csewardj
954530f808586c19a4a6999eed07e604a456c80a3csewardj   if ((close(fd)) < 0)
964530f808586c19a4a6999eed07e604a456c80a3csewardj     perror("close"),exit(1);
974530f808586c19a4a6999eed07e604a456c80a3csewardj   if ((unlink(".ktemp")) < 0)
984530f808586c19a4a6999eed07e604a456c80a3csewardj     perror("unlink"),exit(1);
994530f808586c19a4a6999eed07e604a456c80a3csewardj
1004530f808586c19a4a6999eed07e604a456c80a3csewardj   return 0;
1014530f808586c19a4a6999eed07e604a456c80a3csewardj}
102