| #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); |
| } |