]> git.lizzy.rs Git - plan9front.git/blob - sys/src/libthread/ioproc.c
libthread: reimplemented i/o procs using new interrupt ctl message
[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         qlock(io);
15         if(++io->intr == 1)
16                 write(io->ctl, "interrupt", 9);
17         qunlock(io);
18 }
19
20 static void
21 xioproc(void *a)
22 {
23         Channel *c;
24         Ioproc *io;
25         Iocall *r;
26
27         c = a;
28         if(io = mallocz(sizeof(*io), 1)){
29                 char buf[128];
30
31                 snprint(buf, sizeof(buf), "/proc/%d/ctl", getpid());
32                 if((io->ctl = open(buf, OWRITE)) < 0){
33                         free(io);
34                         io = nil;
35                 } else {
36                         if((io->creply = chancreate(sizeof(void*), 0)) == nil){
37                                 close(io->ctl);
38                                 free(io);
39                                 io = nil;
40                         } else
41                                 io->c = c;
42                 }
43         }
44         while(send(c, &io) < 0)
45                 ;
46         if(io == nil)
47                 return;
48
49         for(;;){
50                 while(recv(io->c, &r) < 0)
51                         ;
52                 if(r == 0)
53                         break;
54                 if(io->intr){
55                         r->ret = -1;
56                         strcpy(r->err, "interrupted");
57                 } else if((r->ret = r->op(&r->arg)) < 0)
58                         rerrstr(r->err, sizeof r->err);
59                 qlock(io);
60                 if(io->intr){
61                         io->intr = 0;
62                         write(io->ctl, "nointerrupt", 11);
63                 }
64                 while(send(io->creply, &r) < 0)
65                         ;
66                 qunlock(io);
67         }
68
69         close(io->ctl);
70         chanfree(io->c);
71         chanfree(io->creply);
72         free(io);
73 }
74
75 Ioproc*
76 ioproc(void)
77 {
78         Channel *c;
79         Ioproc *io;
80
81         if((c = chancreate(sizeof(void*), 0)) == nil)
82                 sysfatal("ioproc chancreate");
83         proccreate(xioproc, c, STACK);
84         while(recv(c, &io) < 0)
85                 ;
86         if(io == nil)
87                 sysfatal("ioproc alloc");
88         return io;
89 }
90
91 void
92 closeioproc(Ioproc *io)
93 {
94         if(io == nil)
95                 return;
96         iointerrupt(io);
97         while(sendp(io->c, nil) < 0)
98                 ;
99 }