]> git.lizzy.rs Git - plan9front.git/blob - sys/src/libplumb/event.c
archacpi: make *acpi=1 the default
[plan9front.git] / sys / src / libplumb / event.c
1 #include <u.h>
2 #include <libc.h>
3 #include <draw.h>
4 #include <event.h>
5 #include "plumb.h"
6
7 typedef struct EQueue EQueue;
8
9 struct EQueue
10 {
11         int             id;
12         char            *buf;
13         int             nbuf;
14         EQueue  *next;
15 };
16
17 static  EQueue  *equeue;
18 static  Lock            eqlock;
19
20 static
21 int
22 partial(int id, Event *e, uchar *b, int n)
23 {
24         EQueue *eq, *p;
25         int nmore;
26
27         lock(&eqlock);
28         for(eq = equeue; eq != nil; eq = eq->next)
29                 if(eq->id == id)
30                         break;
31         unlock(&eqlock);
32         if(eq == nil)
33                 return 0;
34         /* partial message exists for this id */
35         eq->buf = realloc(eq->buf, eq->nbuf+n);
36         if(eq->buf == nil)
37                 drawerror(display, "eplumb: cannot allocate buffer");
38         memmove(eq->buf+eq->nbuf, b, n);
39         eq->nbuf += n;
40         e->v = plumbunpackpartial((char*)eq->buf, eq->nbuf, &nmore);
41         if(nmore == 0){ /* no more to read in this message */
42                 lock(&eqlock);
43                 if(eq == equeue)
44                         equeue = eq->next;
45                 else{
46                         for(p = equeue; p!=nil && p->next!=eq; p = p->next)
47                                 ;
48                         if(p == nil)
49                                 drawerror(display, "eplumb: bad event queue");
50                         p->next = eq->next;
51                 }
52                 unlock(&eqlock);
53                 free(eq->buf);
54                 free(eq);
55         }
56         return 1;
57 }
58
59 static
60 void
61 addpartial(int id, char *b, int n)
62 {
63         EQueue *eq;
64
65         eq = malloc(sizeof(EQueue));
66         if(eq == nil)
67                 return;
68         eq->id = id;
69         eq->nbuf = n;
70         eq->buf = malloc(n);
71         if(eq->buf == nil){
72                 free(eq);
73                 return;
74         }
75         memmove(eq->buf, b, n);
76         lock(&eqlock);
77         eq->next = equeue;
78         equeue = eq;
79         unlock(&eqlock);
80 }
81
82 static
83 int
84 plumbevent(int id, Event *e, uchar *b, int n)
85 {
86         int nmore;
87
88         if(partial(id, e, b, n) == 0){
89                 /* no partial message already waiting for this id */
90                 e->v = plumbunpackpartial((char*)b, n, &nmore);
91                 if(nmore > 0)   /* incomplete message */
92                         addpartial(id, (char*)b, n);
93         }
94         if(e->v == nil)
95                 return 0;
96         return id;
97 }
98
99 int
100 eplumb(int key, char *port)
101 {
102         int fd;
103
104         fd = plumbopen(port, OREAD|OCEXEC);
105         if(fd < 0)
106                 return -1;
107         return estartfn(key, fd, 8192, plumbevent);
108 }