1 619085f0 2004-12-25 devnull #include <u.h>
2 619085f0 2004-12-25 devnull #include <libc.h>
3 619085f0 2004-12-25 devnull #include <thread.h>
4 619085f0 2004-12-25 devnull #include "ioproc.h"
8 619085f0 2004-12-25 devnull STACK = 32768,
12 619085f0 2004-12-25 devnull iointerrupt(Ioproc *io)
14 619085f0 2004-12-25 devnull if(!io->inuse)
16 af89fc10 2005-01-06 devnull fprint(2, "bug: cannot iointerrupt %p yet\n", io);
19 619085f0 2004-12-25 devnull static void
20 619085f0 2004-12-25 devnull xioproc(void *a)
22 619085f0 2004-12-25 devnull Ioproc *io, *x;
24 2c87dda8 2004-12-28 devnull threadsetname("ioproc");
27 619085f0 2004-12-25 devnull * first recvp acquires the ioproc.
28 619085f0 2004-12-25 devnull * second tells us that the data is ready.
31 619085f0 2004-12-25 devnull while(recv(io->c, &x) == -1)
33 619085f0 2004-12-25 devnull if(x == 0) /* our cue to leave */
35 619085f0 2004-12-25 devnull assert(x == io);
37 619085f0 2004-12-25 devnull /* caller is now committed -- even if interrupted he'll return */
38 619085f0 2004-12-25 devnull while(recv(io->creply, &x) == -1)
40 619085f0 2004-12-25 devnull if(x == 0) /* caller backed out */
41 619085f0 2004-12-25 devnull continue;
42 619085f0 2004-12-25 devnull assert(x == io);
44 619085f0 2004-12-25 devnull io->ret = io->op(&io->arg);
45 619085f0 2004-12-25 devnull if(io->ret < 0)
46 619085f0 2004-12-25 devnull rerrstr(io->err, sizeof io->err);
47 619085f0 2004-12-25 devnull while(send(io->creply, &io) == -1)
49 619085f0 2004-12-25 devnull while(recv(io->creply, &x) == -1)
55 619085f0 2004-12-25 devnull ioproc(void)
57 619085f0 2004-12-25 devnull Ioproc *io;
59 619085f0 2004-12-25 devnull io = mallocz(sizeof(*io), 1);
60 619085f0 2004-12-25 devnull if(io == nil)
61 619085f0 2004-12-25 devnull sysfatal("ioproc malloc: %r");
62 619085f0 2004-12-25 devnull io->c = chancreate(sizeof(void*), 0);
63 619085f0 2004-12-25 devnull chansetname(io->c, "ioc%p", io->c);
64 619085f0 2004-12-25 devnull io->creply = chancreate(sizeof(void*), 0);
65 619085f0 2004-12-25 devnull chansetname(io->creply, "ior%p", io->c);
66 619085f0 2004-12-25 devnull io->tid = proccreate(xioproc, io, STACK);
67 619085f0 2004-12-25 devnull return io;
71 619085f0 2004-12-25 devnull closeioproc(Ioproc *io)
73 619085f0 2004-12-25 devnull if(io == nil)
75 619085f0 2004-12-25 devnull iointerrupt(io);
76 619085f0 2004-12-25 devnull while(send(io->c, 0) == -1)
78 619085f0 2004-12-25 devnull chanfree(io->c);
79 619085f0 2004-12-25 devnull chanfree(io->creply);
80 619085f0 2004-12-25 devnull free(io);
84 619085f0 2004-12-25 devnull iocall(Ioproc *io, long (*op)(va_list*), ...)
86 619085f0 2004-12-25 devnull char e[ERRMAX];
87 619085f0 2004-12-25 devnull int ret, inted;
88 619085f0 2004-12-25 devnull Ioproc *msg;
90 619085f0 2004-12-25 devnull if(send(io->c, &io) == -1){
91 619085f0 2004-12-25 devnull werrstr("interrupted");
92 619085f0 2004-12-25 devnull return -1;
94 619085f0 2004-12-25 devnull assert(!io->inuse);
95 619085f0 2004-12-25 devnull io->inuse = 1;
96 619085f0 2004-12-25 devnull io->op = op;
97 619085f0 2004-12-25 devnull va_start(io->arg, op);
98 619085f0 2004-12-25 devnull msg = io;
99 619085f0 2004-12-25 devnull inted = 0;
100 619085f0 2004-12-25 devnull while(send(io->creply, &msg) == -1){
101 619085f0 2004-12-25 devnull msg = nil;
102 619085f0 2004-12-25 devnull inted = 1;
104 619085f0 2004-12-25 devnull if(inted){
105 619085f0 2004-12-25 devnull werrstr("interrupted");
106 619085f0 2004-12-25 devnull return -1;
110 619085f0 2004-12-25 devnull * If we get interrupted, we have stick around so that
111 619085f0 2004-12-25 devnull * the IO proc has someone to talk to. Send it an interrupt
112 619085f0 2004-12-25 devnull * and try again.
114 619085f0 2004-12-25 devnull inted = 0;
115 619085f0 2004-12-25 devnull while(recv(io->creply, nil) == -1){
116 619085f0 2004-12-25 devnull inted = 1;
117 619085f0 2004-12-25 devnull iointerrupt(io);
119 619085f0 2004-12-25 devnull USED(inted);
120 619085f0 2004-12-25 devnull va_end(io->arg);
121 619085f0 2004-12-25 devnull ret = io->ret;
122 619085f0 2004-12-25 devnull if(ret < 0)
123 619085f0 2004-12-25 devnull strecpy(e, e+sizeof e, io->err);
124 619085f0 2004-12-25 devnull io->inuse = 0;
126 619085f0 2004-12-25 devnull /* release resources */
127 619085f0 2004-12-25 devnull while(send(io->creply, &io) == -1)
129 619085f0 2004-12-25 devnull if(ret < 0)
130 619085f0 2004-12-25 devnull errstr(e, sizeof e);
131 619085f0 2004-12-25 devnull return ret;