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