Blame


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