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