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
io(void * arg)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
killer(void * arg)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
main(void)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