blob: 865a9883b4e6ae038dac52cb32301d3937e6d851 [file] [log] [blame]
rsccfa37a72004-04-10 18:53:55 +00001.TH IOPROC 3
rscb2cfc4e2003-09-30 17:47:41 +00002.SH NAME
3closeioproc,
4iocall,
5ioclose,
6iointerrupt,
7iodial,
8ioopen,
9ioproc,
10ioread,
rsc058b0112005-01-03 06:40:20 +000011ioread9pmsg,
rscb2cfc4e2003-09-30 17:47:41 +000012ioreadn,
rsc058b0112005-01-03 06:40:20 +000013iorecvfd,
14iosendfd,
15iosleep,
rscb2cfc4e2003-09-30 17:47:41 +000016iowrite \- 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
29typedef struct Ioproc Ioproc;
30.sp
31Ioproc* ioproc(void);
32.XX
rscb2cfc4e2003-09-30 17:47:41 +000033int ioclose(Ioproc *io, int fd);
rscb2cfc4e2003-09-30 17:47:41 +000034int iodial(Ioproc *io, char *addr, char *local, char *dir, char *cdfp);
rsc058b0112005-01-03 06:40:20 +000035int ioopen(Ioproc *io, char *file, int omode);
36long ioread(Ioproc *io, int fd, void *a, long n);
37int ioread9pmsg(Ioproc *io, int fd, void *a, uint n);
38long ioreadn(Ioproc *io, int fd, void *a, long n);
39int iorecvfd(int socket);
40int iosendfd(int socket, int fd);
41int iosleep(int milli);
42long iowrite(Ioproc *io, int fd, void *a, long n);
rscb2cfc4e2003-09-30 17:47:41 +000043.XX
44void iointerrupt(Ioproc *io);
45void closeioproc(Ioproc *io);
46.XX
47long iocall(Ioproc *io, long (*op)(va_list *arg), ...);
48.EE
49.SH DESCRIPTION
50.PP
51These routines provide access to I/O in slave procs.
52Since the I/O itself is done in a slave proc, other threads
53in the calling proc can run while the calling thread
54waits for the I/O to complete.
55.PP
56.I Ioproc
57forks a new slave proc and returns a pointer to the
58.B Ioproc
59associated with it.
60.I Ioproc
61uses
62.I mallocz
63and
64.IR proccreate ;
65if either fails, it calls
66.I sysfatal
67rather than return an error.
68.PP
rsc058b0112005-01-03 06:40:20 +000069.IR Ioclose ,
70.IR iodial ,
71.IR ioopen ,
rscb2cfc4e2003-09-30 17:47:41 +000072.IR ioread ,
rsc058b0112005-01-03 06:40:20 +000073.IR ioread9pmsg ,
rscb2cfc4e2003-09-30 17:47:41 +000074.IR ioreadn ,
rsc058b0112005-01-03 06:40:20 +000075.IR iorecvfd ,
76.IR iosendfd ,
77.IR iosleep ,
rscb2cfc4e2003-09-30 17:47:41 +000078and
rsc058b0112005-01-03 06:40:20 +000079.I iowrite
80execute the
rscb2cfc4e2003-09-30 17:47:41 +000081similarly named library or system calls
82(see
rsc058b0112005-01-03 06:40:20 +000083.IR close (2),
84.IR dial (3),
rscbf8a59f2004-04-11 03:42:27 +000085.IR open (3),
86.IR read (3),
rsc058b0112005-01-03 06:40:20 +000087.IR fcall (3),
88.IR sendfd (3),
rscb2cfc4e2003-09-30 17:47:41 +000089and
rsc058b0112005-01-03 06:40:20 +000090.IR sleep (3))
rscb2cfc4e2003-09-30 17:47:41 +000091in the slave process associated with
92.IR io .
93It is an error to execute more than one call
94at a time in an I/O proc.
95.PP
96.I Iointerrupt
97interrupts the call currently executing in the I/O proc.
98If no call is executing,
99.IR iointerrupt
100is a no-op.
101.PP
102.I Closeioproc
103terminates the I/O proc and frees the associated
104.B Ioproc .
105.PP
106.I Iocall
107is a primitive that may be used to implement
108more slave I/O routines.
109.I Iocall
110arranges for
111.I op
112to be called in
113.IR io 's
114proc, with
115.I arg
116set to the variable parameter list,
117returning the value that
118.I op
119returns.
120.SH EXAMPLE
121Relay messages between two file descriptors,
122counting the total number of bytes seen:
123.IP
124.EX
125.ta +\w'xxxx'u +\w'xxxx'u +\w'xxxx'u
126int tot;
127
128void
129relaythread(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
145void
146relay(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
grai881e5d12008-07-22 03:26:08 +1000157The two
rscb2cfc4e2003-09-30 17:47:41 +0000158.I relaythread
grai881e5d12008-07-22 03:26:08 +1000159instances are running in the same proc, so the
rscb2cfc4e2003-09-30 17:47:41 +0000160common access to
161.I tot
grai881e5d12008-07-22 03:26:08 +1000162is safe.
rscb2cfc4e2003-09-30 17:47:41 +0000163.PP
164Implement
165.IR ioread :
166.IP
167.EX
168static 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
181long
182ioread(Ioproc *io, int fd, void *a, long n)
183{
184 return iocall(io, _ioread, fd, a, n);
185}
186.EE
187.SH SOURCE
rscc3674de2005-01-11 17:37:33 +0000188.B \*9/src/libthread
rscb2cfc4e2003-09-30 17:47:41 +0000189.SH SEE ALSO
rscbf8a59f2004-04-11 03:42:27 +0000190.IR dial (3),
191.IR open (3),
192.IR read (3),
193.IR thread (3)
rsc058b0112005-01-03 06:40:20 +0000194.SH BUGS
195.I Iointerrupt
196is currently unimplemented.
rsc973131a2006-02-14 19:39:40 +0000197.PP
198C99 disallows the use of pointers to
199.BR va_list .
200This interface will have to change to
201use pointers to a structure containing a
202.BR va_list .