]> git.lizzy.rs Git - plan9front.git/blob - sys/src/lib9p/queue.c
ndb/dns: lookup *all* entries in dblookup(), v4 and v6 queries in parallel, remove...
[plan9front.git] / sys / src / lib9p / queue.c
1 #include <u.h>
2 #include <libc.h>
3 #include <thread.h>
4 #include <fcall.h>
5 #include <9p.h>
6
7 static void
8 _reqqueueproc(void *v)
9 {
10         Reqqueue *q;
11         Req *r;
12         void (*f)(Req *);
13         int fd;
14         char *buf;
15
16         q = v;
17         rfork(RFNOTEG);
18
19         buf = smprint("/proc/%d/ctl", getpid());
20         fd = open(buf, OWRITE);
21         free(buf);
22         
23         for(;;){
24                 qlock(q);
25                 q->flush = 0;
26                 if(fd >= 0)
27                         write(fd, "nointerrupt", 11);
28                 q->cur = nil;
29                 while(q->next == q)
30                         rsleep(q);
31                 r = (Req*)(((char*)q->next) - ((char*)&((Req*)0)->qu));
32                 r->qu.next->prev = r->qu.prev;
33                 r->qu.prev->next = r->qu.next;
34                 f = r->qu.f;
35                 memset(&r->qu, 0, sizeof(r->qu));
36                 q->cur = r;
37                 qunlock(q);
38                 if(f == nil)
39                         break;
40                 f(r);
41         }
42
43         free(r);
44         free(q);
45         threadexits(nil);
46 }
47
48 Reqqueue *
49 reqqueuecreate(void)
50 {
51         Reqqueue *q;
52
53         q = emalloc9p(sizeof(*q));
54         memset(q, 0, sizeof(*q));
55         q->l = q;
56         q->next = q->prev = q;
57         q->pid = proccreate(_reqqueueproc, q, mainstacksize);
58         return q;
59 }
60
61 void
62 reqqueuepush(Reqqueue *q, Req *r, void (*f)(Req *))
63 {
64         qlock(q);
65         r->qu.f = f;
66         r->qu.next = q;
67         r->qu.prev = q->prev;
68         q->prev->next = &r->qu;
69         q->prev = &r->qu;
70         rwakeup(q);
71         qunlock(q);
72 }
73
74 void
75 reqqueueflush(Reqqueue *q, Req *r)
76 {
77         qlock(q);
78         if(q->cur == r){
79                 threadint(q->pid);
80                 q->flush++;
81                 qunlock(q);
82         }else{
83                 if(r->qu.next != nil){
84                         r->qu.next->prev = r->qu.prev;
85                         r->qu.prev->next = r->qu.next;
86                 }
87                 memset(&r->qu, 0, sizeof(r->qu));
88                 qunlock(q);
89                 respond(r, "interrupted");
90         }
91 }
92
93 void
94 reqqueuefree(Reqqueue *q)
95 {
96         Req *r;
97
98         if(q == nil)
99                 return;
100         r = emalloc9p(sizeof(Req));
101         reqqueuepush(q, r, nil);
102 }