]> git.lizzy.rs Git - plan9front.git/blob - sys/src/libthread/ioproc.c
threadimpl.h: remove Printsize as well (unused)
[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->ctl < 0)
15                 return;
16         qlock(io);
17         if(++io->intr == 1)
18                 write(io->ctl, "interrupt", 9);
19         qunlock(io);
20 }
21
22 static int
23 openprocctl(void)
24 {
25         char buf[32];
26
27         snprint(buf, sizeof(buf), "/proc/%lud/ctl", (ulong)getpid());
28         return open(buf, OWRITE|OCEXEC);
29 }
30
31 static void
32 xioproc(void *a)
33 {
34         Channel *c;
35         Ioproc *io;
36         Iocall *r;
37
38         c = a;
39         if(io = mallocz(sizeof(*io), 1)){
40                 /*
41                  * open might fail, ignore it for programs like factotum
42                  * that don't use iointerrupt() anyway.
43                  */
44                 io->ctl = openprocctl();
45                 if((io->creply = chancreate(sizeof(void*), 0)) == nil){
46                         if(io->ctl >= 0)
47                                 close(io->ctl);
48                         free(io);
49                         io = nil;
50                 } else
51                         io->c = c;
52         }
53         while(send(c, &io) < 0)
54                 ;
55         if(io == nil)
56                 return;
57
58         for(;;){
59                 while(recv(io->c, &r) < 0)
60                         ;
61                 if(r == 0)
62                         break;
63                 if(io->intr){
64                         r->ret = -1;
65                         strcpy(r->err, "interrupted");
66                 } else if((r->ret = r->op(&r->arg)) < 0)
67                         rerrstr(r->err, sizeof r->err);
68                 qlock(io);
69                 if(io->intr){
70                         io->intr = 0;
71                         if(io->ctl >= 0)
72                                 write(io->ctl, "nointerrupt", 11);
73                 }
74                 while(send(io->creply, &r) < 0)
75                         ;
76                 qunlock(io);
77         }
78
79         if(io->ctl >= 0)
80                 close(io->ctl);
81         chanfree(io->c);
82         chanfree(io->creply);
83         free(io);
84 }
85
86 Ioproc*
87 ioproc(void)
88 {
89         Channel *c;
90         Ioproc *io;
91
92         if((c = chancreate(sizeof(void*), 0)) == nil)
93                 sysfatal("ioproc chancreate");
94         proccreate(xioproc, c, STACK);
95         while(recv(c, &io) < 0)
96                 ;
97         if(io == nil)
98                 sysfatal("ioproc alloc");
99         return io;
100 }
101
102 void
103 closeioproc(Ioproc *io)
104 {
105         if(io == nil)
106                 return;
107         iointerrupt(io);
108         while(sendp(io->c, nil) < 0)
109                 ;
110 }