.TH IOPROC 3 .SH NAME closeioproc, iocall, ioclose, iointerrupt, iodial, ioopen, ioproc, ioread, ioread9pmsg, ioreadn, iorecvfd, iosendfd, iosleep, iowrite \- slave I/O processes for threaded programs .SH SYNOPSIS .PP .de XX .ift .sp 0.5 .ifn .sp .. .EX .ta \w'Ioproc* 'u #include #include #include .sp typedef struct Ioproc Ioproc; .sp Ioproc* ioproc(void); .XX int ioclose(Ioproc *io, int fd); int iodial(Ioproc *io, char *addr, char *local, char *dir, char *cdfp); int ioopen(Ioproc *io, char *file, int omode); long ioread(Ioproc *io, int fd, void *a, long n); int ioread9pmsg(Ioproc *io, int fd, void *a, uint n); long ioreadn(Ioproc *io, int fd, void *a, long n); int iorecvfd(Ioproc *io, int socket); int iosendfd(Ioproc *io, int socket, int fd); int iosleep(Ioproc *io, long milli); long iowrite(Ioproc *io, int fd, void *a, long n); .XX void iointerrupt(Ioproc *io); void closeioproc(Ioproc *io); .XX long iocall(Ioproc *io, long (*op)(va_list *arg), ...); .EE .SH DESCRIPTION .PP These routines provide access to I/O in slave procs. Since the I/O itself is done in a slave proc, other threads in the calling proc can run while the calling thread waits for the I/O to complete. .PP .I Ioproc forks a new slave proc and returns a pointer to the .B Ioproc associated with it. .I Ioproc uses .I mallocz and .IR proccreate ; if either fails, it calls .I sysfatal rather than return an error. .PP .IR Ioclose , .IR iodial , .IR ioopen , .IR ioread , .IR ioread9pmsg , .IR ioreadn , .IR iorecvfd , .IR iosendfd , .IR iosleep , and .I iowrite execute the similarly named library or system calls (see .MR close (2) , .MR dial (3) , .MR open (3) , .MR read (3) , .MR fcall (3) , .MR sendfd (3) , and .MR sleep (3) ) in the slave process associated with .IR io . It is an error to execute more than one call at a time in an I/O proc. .PP .I Iointerrupt interrupts the call currently executing in the I/O proc. If no call is executing, .IR iointerrupt is a no-op. .PP .I Closeioproc terminates the I/O proc and frees the associated .B Ioproc . .PP .I Iocall is a primitive that may be used to implement more slave I/O routines. .I Iocall arranges for .I op to be called in .IR io 's proc, with .I arg set to the variable parameter list, returning the value that .I op returns. .SH EXAMPLE Relay messages between two file descriptors, counting the total number of bytes seen: .IP .EX .ta +\w'xxxx'u +\w'xxxx'u +\w'xxxx'u int tot; void relaythread(void *v) { int *fd, n; char buf[1024]; Ioproc *io; fd = v; io = ioproc(); while((n = ioread(io, fd[0], buf, sizeof buf)) > 0){ if(iowrite(io, fd[1], buf, n) != n) sysfatal("iowrite: %r"); tot += n; } closeioproc(io); } void relay(int fd0, int fd1) { int fd[4]; fd[0] = fd[3] = fd0; fd[1] = fd[2] = fd1; threadcreate(relaythread, fd, 8192); threadcreate(relaythread, fd+2, 8192); } .EE .LP The two .I relaythread instances are running in the same proc, so the common access to .I tot is safe. .PP Implement .IR ioread : .IP .EX static long _ioread(va_list *arg) { int fd; void *a; long n; fd = va_arg(*arg, int); a = va_arg(*arg, void*); n = va_arg(*arg, long); return read(fd, a, n); } long ioread(Ioproc *io, int fd, void *a, long n) { return iocall(io, _ioread, fd, a, n); } .EE .SH SOURCE .B \*9/src/libthread .SH SEE ALSO .MR dial (3) , .MR open (3) , .MR read (3) , .MR thread (3) .SH BUGS .I Iointerrupt is currently unimplemented. .PP C99 disallows the use of pointers to .BR va_list . This interface will have to change to use pointers to a structure containing a .BR va_list .