xref: /plan9/sys/src/lib9p/req.c (revision 9a747e4fd48b9f4522c70c07e8f882a15030f964)
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
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*
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
33 freereqpool(Reqpool *p)
34 {
35 	freemap(p->map, (void(*)(void*))p->destroy);
36 	free(p);
37 }
38 
39 Req*
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 		return nil;
53 	}
54 
55 	return r;
56 }
57 
58 Req*
59 lookupreq(Reqpool *pool, ulong tag)
60 {
61 if(chatty9p > 1)
62 	fprint(2, "lookupreq %lud\n", tag);
63 	return lookupkey(pool->map, tag);
64 }
65 
66 void
67 closereq(Req *r)
68 {
69 	if(r == nil)
70 		return;
71 
72 if(chatty9p > 1)
73 	fprint(2, "closereq %p %ld\n", r, r->ref.ref);
74 
75 	if(decref(&r->ref) == 0){
76 		if(r->fid)
77 			closefid(r->fid);
78 		if(r->newfid)
79 			closefid(r->newfid);
80 		if(r->oldreq)
81 			closereq(r->oldreq);
82 		switch(r->ifcall.type){
83 		case Tstat:
84 			free(r->ofcall.stat);
85 			free(r->d.name);
86 			free(r->d.uid);
87 			free(r->d.gid);
88 			free(r->d.muid);
89 			break;
90 		}
91 		if(r->pool->destroy)
92 			r->pool->destroy(r);
93 		free(r->buf);
94 		free(r->rbuf);
95 		free(r);
96 	}
97 }
98 
99 Req*
100 removereq(Reqpool *pool, ulong tag)
101 {
102 if(chatty9p > 1)
103 	fprint(2, "removereq %lud\n", tag);
104 	return deletekey(pool->map, tag);
105 }
106