mirror of
https://github.com/9fans/plan9port.git
synced 2025-01-12 11:10:07 +00:00
d32deab17b
Suggested by G. Brandon Robinson.
202 lines
3.5 KiB
Groff
202 lines
3.5 KiB
Groff
.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 <u.h>
|
|
#include <libc.h>
|
|
#include <thread.h>
|
|
.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 .
|