rsc | cfa37a7 | 2004-04-10 18:53:55 +0000 | [diff] [blame] | 1 | .TH IOPROC 3 |
rsc | b2cfc4e | 2003-09-30 17:47:41 +0000 | [diff] [blame] | 2 | .SH NAME |
| 3 | closeioproc, |
| 4 | iocall, |
| 5 | ioclose, |
| 6 | iointerrupt, |
| 7 | iodial, |
| 8 | ioopen, |
| 9 | ioproc, |
| 10 | ioread, |
rsc | 058b011 | 2005-01-03 06:40:20 +0000 | [diff] [blame] | 11 | ioread9pmsg, |
rsc | b2cfc4e | 2003-09-30 17:47:41 +0000 | [diff] [blame] | 12 | ioreadn, |
rsc | 058b011 | 2005-01-03 06:40:20 +0000 | [diff] [blame] | 13 | iorecvfd, |
| 14 | iosendfd, |
| 15 | iosleep, |
rsc | b2cfc4e | 2003-09-30 17:47:41 +0000 | [diff] [blame] | 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 |
rsc | b2cfc4e | 2003-09-30 17:47:41 +0000 | [diff] [blame] | 33 | int ioclose(Ioproc *io, int fd); |
rsc | b2cfc4e | 2003-09-30 17:47:41 +0000 | [diff] [blame] | 34 | int iodial(Ioproc *io, char *addr, char *local, char *dir, char *cdfp); |
rsc | 058b011 | 2005-01-03 06:40:20 +0000 | [diff] [blame] | 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(int socket); |
| 40 | int iosendfd(int socket, int fd); |
| 41 | int iosleep(int milli); |
| 42 | long iowrite(Ioproc *io, int fd, void *a, long n); |
rsc | b2cfc4e | 2003-09-30 17:47:41 +0000 | [diff] [blame] | 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 |
rsc | 058b011 | 2005-01-03 06:40:20 +0000 | [diff] [blame] | 69 | .IR Ioclose , |
| 70 | .IR iodial , |
| 71 | .IR ioopen , |
rsc | b2cfc4e | 2003-09-30 17:47:41 +0000 | [diff] [blame] | 72 | .IR ioread , |
rsc | 058b011 | 2005-01-03 06:40:20 +0000 | [diff] [blame] | 73 | .IR ioread9pmsg , |
rsc | b2cfc4e | 2003-09-30 17:47:41 +0000 | [diff] [blame] | 74 | .IR ioreadn , |
rsc | 058b011 | 2005-01-03 06:40:20 +0000 | [diff] [blame] | 75 | .IR iorecvfd , |
| 76 | .IR iosendfd , |
| 77 | .IR iosleep , |
rsc | b2cfc4e | 2003-09-30 17:47:41 +0000 | [diff] [blame] | 78 | and |
rsc | 058b011 | 2005-01-03 06:40:20 +0000 | [diff] [blame] | 79 | .I iowrite |
| 80 | execute the |
rsc | b2cfc4e | 2003-09-30 17:47:41 +0000 | [diff] [blame] | 81 | similarly named library or system calls |
| 82 | (see |
rsc | 058b011 | 2005-01-03 06:40:20 +0000 | [diff] [blame] | 83 | .IR close (2), |
| 84 | .IR dial (3), |
rsc | bf8a59f | 2004-04-11 03:42:27 +0000 | [diff] [blame] | 85 | .IR open (3), |
| 86 | .IR read (3), |
rsc | 058b011 | 2005-01-03 06:40:20 +0000 | [diff] [blame] | 87 | .IR fcall (3), |
| 88 | .IR sendfd (3), |
rsc | b2cfc4e | 2003-09-30 17:47:41 +0000 | [diff] [blame] | 89 | and |
rsc | 058b011 | 2005-01-03 06:40:20 +0000 | [diff] [blame] | 90 | .IR sleep (3)) |
rsc | b2cfc4e | 2003-09-30 17:47:41 +0000 | [diff] [blame] | 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 |
grai | 881e5d1 | 2008-07-22 03:26:08 +1000 | [diff] [blame] | 157 | The two |
rsc | b2cfc4e | 2003-09-30 17:47:41 +0000 | [diff] [blame] | 158 | .I relaythread |
grai | 881e5d1 | 2008-07-22 03:26:08 +1000 | [diff] [blame] | 159 | instances are running in the same proc, so the |
rsc | b2cfc4e | 2003-09-30 17:47:41 +0000 | [diff] [blame] | 160 | common access to |
| 161 | .I tot |
grai | 881e5d1 | 2008-07-22 03:26:08 +1000 | [diff] [blame] | 162 | is safe. |
rsc | b2cfc4e | 2003-09-30 17:47:41 +0000 | [diff] [blame] | 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 |
rsc | c3674de | 2005-01-11 17:37:33 +0000 | [diff] [blame] | 188 | .B \*9/src/libthread |
rsc | b2cfc4e | 2003-09-30 17:47:41 +0000 | [diff] [blame] | 189 | .SH SEE ALSO |
rsc | bf8a59f | 2004-04-11 03:42:27 +0000 | [diff] [blame] | 190 | .IR dial (3), |
| 191 | .IR open (3), |
| 192 | .IR read (3), |
| 193 | .IR thread (3) |
rsc | 058b011 | 2005-01-03 06:40:20 +0000 | [diff] [blame] | 194 | .SH BUGS |
| 195 | .I Iointerrupt |
| 196 | is currently unimplemented. |
rsc | 973131a | 2006-02-14 19:39:40 +0000 | [diff] [blame] | 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 . |