Blob


1 #include "threadimpl.h"
3 enum
4 {
5 STACK = 8192,
6 };
8 void
9 iointerrupt(Ioproc *io)
10 {
11 if(!io->inuse)
12 return;
13 threadint(io->tid);
14 }
16 static void
17 xioproc(void *a)
18 {
19 Ioproc *io, *x;
20 io = a;
21 /*
22 * first recvp acquires the ioproc.
23 * second tells us that the data is ready.
24 */
25 for(;;){
26 while(recv(io->c, &x) == -1)
27 ;
28 if(x == 0) /* our cue to leave */
29 break;
30 assert(x == io);
32 /* caller is now committed -- even if interrupted he'll return */
33 while(recv(io->creply, &x) == -1)
34 ;
35 if(x == 0) /* caller backed out */
36 continue;
37 assert(x == io);
39 io->ret = io->op(&io->arg);
40 if(io->ret < 0)
41 rerrstr(io->err, sizeof io->err);
42 while(send(io->creply, &io) == -1)
43 ;
44 while(recv(io->creply, &x) == -1)
45 ;
46 }
47 }
49 Ioproc*
50 ioproc(void)
51 {
52 Ioproc *io;
54 io = mallocz(sizeof(*io), 1);
55 if(io == nil)
56 sysfatal("ioproc malloc: %r");
57 io->c = chancreate(sizeof(void*), 0);
58 io->creply = chancreate(sizeof(void*), 0);
59 io->tid = proccreate(xioproc, io, STACK);
60 return io;
61 }
63 void
64 closeioproc(Ioproc *io)
65 {
66 if(io == nil)
67 return;
68 iointerrupt(io);
69 while(send(io->c, 0) == -1)
70 ;
71 chanfree(io->c);
72 chanfree(io->creply);
73 free(io);
74 }