|  | 
 NAME     
 |  |  |  | closeioproc, iocall, ioclose, iointerrupt, iodial, ioopen, ioproc,
    ioread, ioread9pmsg, ioreadn, iorecvfd, iosendfd, iosleep, iowrite
    – slave I/O processes for threaded programs 
 | 
 SYNOPSIS     
 |  |  |  | #include <u.h> #include <libc.h>
 #include <thread.h>
 typedef struct Ioproc Ioproc;
 Ioproc* ioproc(void);
 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);
 void     iointerrupt(Ioproc *io);
 void     closeioproc(Ioproc *io);
 long     iocall(Ioproc *io, long (*op)(va_list *arg), ...);
 
 | 
 DESCRIPTION     
 |  |  |  | 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.
    
    
    
    Ioproc forks a new slave proc and returns a pointer to the Ioproc
    associated with it. Ioproc uses mallocz and proccreate; if either
    fails, it calls sysfatal rather than return an error. 
    
    
    Ioclose, iodial, ioopen, ioread, ioread9pmsg, ioreadn, iorecvfd,
    iosendfd, iosleep, and iowrite execute the similarly named library
    or system calls (see close(2), dial(3), open(3), read(3), fcall(3),
    sendfd(3), and sleep(3)) in the slave process associated with
    io. It is an error to execute more than one call at a time in
    an I/O proc. 
    
    
    Iointerrupt interrupts the call currently executing in the I/O
    proc. If no call is executing, iointerrupt is a no-op. 
    
    
    Closeioproc terminates the I/O proc and frees the associated Ioproc
    . 
    
    
    Iocall is a primitive that may be used to implement more slave
    I/O routines. Iocall arranges for op to be called in io’s proc,
    with arg set to the variable parameter list, returning the value
    that op returns. 
 | 
 EXAMPLE     
 |  |  |  | Relay messages between two file descriptors, counting the total
    number of bytes seen: 
 The two relaythread instances are running in the same proc, so
    the common access to tot is safe. 
    
    
    Implement ioread:|  |  |  | 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);
 
 | 
 
 | 
 
 |  |  |  | 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); 
 | 
 
 | 
 | 
 SOURCE     
 SEE ALSO    
 BUGS     
 |  |  |  | Iointerrupt is currently unimplemented. 
    
    
    C99 disallows the use of pointers to va_list. This interface will
    have to change to use pointers to a structure containing a va_list. 
 | 
 |  |