plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

ioproc.3 (3591B)


      1 .TH IOPROC 3
      2 .SH NAME
      3 closeioproc,
      4 iocall,
      5 ioclose,
      6 iointerrupt,
      7 iodial,
      8 ioopen,
      9 ioproc,
     10 ioread,
     11 ioread9pmsg,
     12 ioreadn,
     13 iorecvfd,
     14 iosendfd,
     15 iosleep,
     16 iowrite \- slave I/O processes for threaded programs
     17 .SH SYNOPSIS
     18 .PP
     19 .de XX
     20 .ift .sp 0.5
     21 .ifn .sp
     22 ..
     23 .EX
     24 .ta \w'Ioproc* 'u
     25 #include <u.h>
     26 #include <libc.h>
     27 #include <thread.h>
     28 .sp
     29 typedef struct Ioproc Ioproc;
     30 .sp
     31 Ioproc*	ioproc(void);
     32 .XX
     33 int	ioclose(Ioproc *io, int fd);
     34 int	iodial(Ioproc *io, char *addr, char *local, char *dir, char *cdfp);
     35 int	ioopen(Ioproc *io, char *file, int omode);
     36 long	ioread(Ioproc *io, int fd, void *a, long n);
     37 int	ioread9pmsg(Ioproc *io, int fd, void *a, uint n);
     38 long	ioreadn(Ioproc *io, int fd, void *a, long n);
     39 int	iorecvfd(Ioproc *io, int socket);
     40 int	iosendfd(Ioproc *io, int socket, int fd);
     41 int	iosleep(Ioproc *io, long milli);
     42 long	iowrite(Ioproc *io, int fd, void *a, long n);
     43 .XX
     44 void	iointerrupt(Ioproc *io);
     45 void	closeioproc(Ioproc *io);
     46 .XX
     47 long	iocall(Ioproc *io, long (*op)(va_list *arg), ...);
     48 .EE
     49 .SH DESCRIPTION
     50 .PP
     51 These routines provide access to I/O in slave procs.
     52 Since the I/O itself is done in a slave proc, other threads
     53 in the calling proc can run while the calling thread
     54 waits for the I/O to complete.
     55 .PP
     56 .I Ioproc
     57 forks a new slave proc and returns a pointer to the
     58 .B Ioproc
     59 associated with it.
     60 .I Ioproc
     61 uses
     62 .I mallocz
     63 and
     64 .IR proccreate ;
     65 if either fails, it calls
     66 .I sysfatal
     67 rather than return an error.
     68 .PP
     69 .IR Ioclose ,
     70 .IR iodial ,
     71 .IR ioopen ,
     72 .IR ioread ,
     73 .IR ioread9pmsg ,
     74 .IR ioreadn ,
     75 .IR iorecvfd ,
     76 .IR iosendfd ,
     77 .IR iosleep ,
     78 and
     79 .I iowrite
     80 execute the
     81 similarly named library or system calls
     82 (see
     83 .MR close (2) ,
     84 .MR dial (3) ,
     85 .MR open (3) ,
     86 .MR read (3) ,
     87 .MR fcall (3) ,
     88 .MR sendfd (3) ,
     89 and
     90 .MR sleep (3) )
     91 in the slave process associated with
     92 .IR io .
     93 It is an error to execute more than one call
     94 at a time in an I/O proc.
     95 .PP
     96 .I Iointerrupt
     97 interrupts the call currently executing in the I/O proc.
     98 If no call is executing,
     99 .IR iointerrupt
    100 is a no-op.
    101 .PP
    102 .I Closeioproc
    103 terminates the I/O proc and frees the associated
    104 .B Ioproc .
    105 .PP
    106 .I Iocall
    107 is a primitive that may be used to implement
    108 more slave I/O routines.
    109 .I Iocall
    110 arranges for
    111 .I op
    112 to be called in
    113 .IR io 's
    114 proc, with
    115 .I arg
    116 set to the variable parameter list,
    117 returning the value that
    118 .I op
    119 returns.
    120 .SH EXAMPLE
    121 Relay messages between two file descriptors,
    122 counting the total number of bytes seen:
    123 .IP
    124 .EX
    125 .ta +\w'xxxx'u +\w'xxxx'u +\w'xxxx'u
    126 int tot;
    127 
    128 void
    129 relaythread(void *v)
    130 {
    131 	int *fd, n;
    132 	char buf[1024];
    133 	Ioproc *io;
    134 
    135 	fd = v;
    136 	io = ioproc();
    137 	while((n = ioread(io, fd[0], buf, sizeof buf)) > 0){
    138 		if(iowrite(io, fd[1], buf, n) != n)
    139 			sysfatal("iowrite: %r");
    140 		tot += n;
    141 	}
    142 	closeioproc(io);
    143 }
    144 
    145 void
    146 relay(int fd0, int fd1)
    147 {
    148 	int fd[4];
    149 
    150 	fd[0] = fd[3] = fd0;
    151 	fd[1] = fd[2] = fd1;
    152 	threadcreate(relaythread, fd, 8192);
    153 	threadcreate(relaythread, fd+2, 8192);
    154 }
    155 .EE
    156 .LP
    157 The two
    158 .I relaythread
    159 instances are running in the same proc, so the
    160 common access to
    161 .I tot
    162 is safe.
    163 .PP
    164 Implement
    165 .IR ioread :
    166 .IP
    167 .EX
    168 static long
    169 _ioread(va_list *arg)
    170 {
    171 	int fd;
    172 	void *a;
    173 	long n;
    174 
    175 	fd = va_arg(*arg, int);
    176 	a = va_arg(*arg, void*);
    177 	n = va_arg(*arg, long);
    178 	return read(fd, a, n);
    179 }
    180 
    181 long
    182 ioread(Ioproc *io, int fd, void *a, long n)
    183 {
    184 	return iocall(io, _ioread, fd, a, n);
    185 }
    186 .EE
    187 .SH SOURCE
    188 .B \*9/src/libthread
    189 .SH SEE ALSO
    190 .MR dial (3) ,
    191 .MR open (3) ,
    192 .MR read (3) ,
    193 .MR thread (3)
    194 .SH BUGS
    195 .I Iointerrupt
    196 is currently unimplemented.
    197 .PP
    198 C99 disallows the use of pointers to
    199 .BR va_list .
    200 This interface will have to change to
    201 use pointers to a structure containing a 
    202 .BR va_list .