|  | #include <u.h> | 
|  | #include <libc.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); | 
|  | 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) | 
|  | { | 
|  | 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); | 
|  | if(r->nflush) | 
|  | fprint(2, "closereq: flushes remaining\n"); | 
|  | 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); | 
|  | } |