Museum

Home

Lab Overview

Retrotechnology Articles

Online Manuals

⇒ (2) — Plan9 4th Edition

Media Vault

Software Library

Restoration Projects

Artifacts Sought

Related Articles

dial(2)

open(2)

read(2)

thread(2)

IOPROC(2)

NAME

closeioproc, iocall, ioclose, iointerrupt, iodial, ioopen, ioproc, ioread, ioreadn, iowrite − slave I/O processes for threaded programs

SYNOPSIS

#include <u.h>
#include <libc.h>
#include <thread.h>
typedef struct Ioproc Ioproc;
Ioproc∗ ioproc(void);
intioopen(Ioproc ∗io, char ∗file, int omode);
intioclose(Ioproc ∗io, int fd);
longioread(Ioproc ∗io, int fd, void ∗a, long n);
longioreadn(Ioproc ∗io, int fd, void ∗a, long n);
longiowrite(Ioproc ∗io, int fd, void ∗a, long n);
intiodial(Ioproc ∗io, char ∗addr, char ∗local, char ∗dir, char ∗cdfp);
voidiointerrupt(Ioproc ∗io);
voidcloseioproc(Ioproc ∗io);
longiocall(Ioproc ∗io, long (∗op)(va_list ∗arg), ...);

DESCRIPTION

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. 

­Ioproc forks a new slave proc and returns a pointer to the ­Ioproc associated with it.  ­Ioproc uses ­mallocz and proccreate; if either fails, it calls ­sysfatal rather than return an error. 

Ioopen, ioclose, ioread, ioreadn, iowrite, and iodial are execute the similarly named library or system calls (see open(2), read(2), and dial(2)) in the slave process associated with io. It is an error to execute more than one call at a time in an I/O proc.

­Iointerrupt interrupts the call currently executing in the I/O proc.  If no call is executing, iointerrupt is a no-op. 

­Closeioproc terminates the I/O proc and frees the associated ­Ioproc . 

­Iocall is a primitive that may be used to implement more slave I/O routines.  ­Iocall arranges for ­op to be called in io’s proc, with ­arg set to the variable parameter list, returning the value that ­op returns. 

EXAMPLE

Relay messages between two file descriptors, counting the total number of bytes seen:

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);
}

If the two ­relaythread instances were running in different procs, the common access to ­tot would be unsafe. 

Implement ioread:

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);
}

SOURCE

­/sys/src/libthread/io∗.c

SEE ALSO

dial(2), open(2), read(2), thread(2)
 

Plan 9  —  August 28, 2002

Typewritten Software • bear@typewritten.org • Edmonds, WA 98026