aboutsummaryrefslogtreecommitdiff
path: root/src/lib9p/req.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib9p/req.c')
-rw-r--r--src/lib9p/req.c112
1 files changed, 112 insertions, 0 deletions
diff --git a/src/lib9p/req.c b/src/lib9p/req.c
new file mode 100644
index 00000000..8e1aaab5
--- /dev/null
+++ b/src/lib9p/req.c
@@ -0,0 +1,112 @@
+#include <u.h>
+#include <libc.h>
+#include <auth.h>
+#include <fcall.h>
+#include <thread.h>
+#include <9p.h>
+
+static void
+increqref(void *v)
+{
+ Req *r;
+
+ r = v;
+ if(r){
+if(chatty9p > 1)
+ fprint(2, "increfreq %p %ld\n", r, r->ref.ref);
+ incref(&r->ref);
+ }
+}
+
+Reqpool*
+allocreqpool(void (*destroy)(Req*))
+{
+ Reqpool *f;
+
+ f = emalloc9p(sizeof *f);
+ f->map = allocmap(increqref);
+ f->destroy = destroy;
+ return f;
+}
+
+void
+freereqpool(Reqpool *p)
+{
+ freemap(p->map, (void(*)(void*))p->destroy);
+ free(p);
+}
+
+Req*
+allocreq(Reqpool *pool, ulong tag)
+{
+ Req *r;
+
+ r = emalloc9p(sizeof *r);
+ r->tag = tag;
+ r->pool = pool;
+
+ increqref(r);
+ increqref(r);
+ if(caninsertkey(pool->map, tag, r) == 0){
+ closereq(r);
+ return nil;
+ }
+
+ return r;
+}
+
+Req*
+lookupreq(Reqpool *pool, ulong tag)
+{
+if(chatty9p > 1)
+ fprint(2, "lookupreq %lud\n", tag);
+ return lookupkey(pool->map, tag);
+}
+
+void
+closereq(Req *r)
+{
+ int i;
+
+ if(r == nil)
+ return;
+
+if(chatty9p > 1)
+ fprint(2, "closereq %p %ld\n", r, r->ref.ref);
+
+ if(decref(&r->ref) == 0){
+ if(r->fid)
+ closefid(r->fid);
+ if(r->newfid)
+ closefid(r->newfid);
+ if(r->afid)
+ closefid(r->afid);
+ if(r->oldreq)
+ closereq(r->oldreq);
+ for(i=0; i<r->nflush; i++)
+ respond(r->flush[i], nil);
+ free(r->flush);
+ switch(r->ifcall.type){
+ case Tstat:
+ free(r->ofcall.stat);
+ free(r->d.name);
+ free(r->d.uid);
+ free(r->d.gid);
+ free(r->d.muid);
+ break;
+ }
+ if(r->pool->destroy)
+ r->pool->destroy(r);
+ free(r->buf);
+ free(r->rbuf);
+ free(r);
+ }
+}
+
+Req*
+removereq(Reqpool *pool, ulong tag)
+{
+if(chatty9p > 1)
+ fprint(2, "removereq %lud\n", tag);
+ return deletekey(pool->map, tag);
+}