/********************************************************
* 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;
}