xref: /plan9/sys/src/lib9p/req.c (revision 375daca8932d0755549a5f8e4d068a24a49927d4)
1 #include <u.h>
2 #include <libc.h>
3 #include <auth.h>
4 #include <fcall.h>
5 #include <thread.h>
6 #include <9p.h>
7 
8 static void
increqref(void * v)9 increqref(void *v)
10 {
11 	Req *r;
12 
13 	r = v;
14 	if(r){
15 if(chatty9p > 1)
16 	fprint(2, "increfreq %p %ld\n", r, r->ref.ref);
17 		incref(&r->ref);
18 	}
19 }
20 
21 Reqpool*
allocreqpool(void (* destroy)(Req *))22 allocreqpool(void (*destroy)(Req*))
23 {
24 	Reqpool *f;
25 
26 	f = emalloc9p(sizeof *f);
27 	f->map = allocmap(increqref);
28 	f->destroy = destroy;
29 	return f;
30 }
31 
32 void
freereqpool(Reqpool * p)33 freereqpool(Reqpool *p)
34 {
35 	freemap(p->map, (void(*)(void*))p->destroy);
36 	free(p);
37 }
38 
39 Req*
allocreq(Reqpool * pool,ulong tag)40 allocreq(Reqpool *pool, ulong tag)
41 {
42 	Req *r;
43 
44 	r = emalloc9p(sizeof *r);
45 	r->tag = tag;
46 	r->pool = pool;
47 
48 	increqref(r);
49 	increqref(r);
50 	if(caninsertkey(pool->map, tag, r) == 0){
51 		closereq(r);
52 		closereq(r);
53 		return nil;
54 	}
55 
56 	return r;
57 }
58 
59 Req*
lookupreq(Reqpool * pool,ulong tag)60 lookupreq(Reqpool *pool, ulong tag)
61 {
62 if(chatty9p > 1)
63 	fprint(2, "lookupreq %lud\n", tag);
64 	return lookupkey(pool->map, tag);
65 }
66 
67 void
closereq(Req * r)68 closereq(Req *r)
69 {
70 	int i;
71 
72 	if(r == nil)
73 		return;
74 
75 if(chatty9p > 1)
76 	fprint(2, "closereq %p %ld\n", r, r->ref.ref);
77 
78 	if(decref(&r->ref) == 0){
79 		if(r->fid)
80 			closefid(r->fid);
81 		if(r->newfid)
82 			closefid(r->newfid);
83 		if(r->afid)
84 			closefid(r->afid);
85 		if(r->oldreq)
86 			closereq(r->oldreq);
87 		for(i=0; i<r->nflush; i++)
88 			respond(r->flush[i], nil);
89 		free(r->flush);
90 		switch(r->ifcall.type){
91 		case Tstat:
92 			free(r->ofcall.stat);
93 			free(r->d.name);
94 			free(r->d.uid);
95 			free(r->d.gid);
96 			free(r->d.muid);
97 			break;
98 		}
99 		if(r->pool->destroy)
100 			r->pool->destroy(r);
101 		free(r->buf);
102 		free(r->rbuf);
103 		free(r);
104 	}
105 }
106 
107 Req*
removereq(Reqpool * pool,ulong tag)108 removereq(Reqpool *pool, ulong tag)
109 {
110 if(chatty9p > 1)
111 	fprint(2, "removereq %lud\n", tag);
112 	return deletekey(pool->map, tag);
113 }
114