123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- .TH IOPROC 2
- .SH NAME
- closeioproc,
- iocall,
- ioclose,
- iointerrupt,
- iodial,
- ioopen,
- ioproc,
- ioread,
- ioreadn,
- 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 ioopen(Ioproc *io, char *file, int omode);
- int ioclose(Ioproc *io, int fd);
- long ioread(Ioproc *io, int fd, void *a, long n);
- long ioreadn(Ioproc *io, int fd, void *a, long n);
- long iowrite(Ioproc *io, int fd, void *a, long n);
- int iodial(Ioproc *io, char *addr, char *local, char *dir, char *cdfp);
- .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 Ioopen ,
- .IR ioclose ,
- .IR ioread ,
- .IR ioreadn ,
- .IR iowrite ,
- and
- .IR iodial
- execute the
- similarly named library or system calls
- (see
- .IR open (2),
- .IR read (2),
- and
- .IR dial (2))
- 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
- If the two
- .I relaythread
- instances were running in different procs, the
- common access to
- .I tot
- would be unsafe.
- .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 /sys/src/libthread/io*.c
- .SH SEE ALSO
- .IR dial (2),
- .IR open (2),
- .IR read (2),
- .IR thread (2)
|