req.c (1628B)
1 #include <u.h> 2 #include <libc.h> 3 #include <fcall.h> 4 #include <thread.h> 5 #include <9p.h> 6 7 static void 8 increqref(void *v) 9 { 10 Req *r; 11 12 r = v; 13 if(r){ 14 if(chatty9p > 1) 15 fprint(2, "increfreq %p %ld\n", r, r->ref.ref); 16 incref(&r->ref); 17 } 18 } 19 20 Reqpool* 21 allocreqpool(void (*destroy)(Req*)) 22 { 23 Reqpool *f; 24 25 f = emalloc9p(sizeof *f); 26 f->map = allocmap(increqref); 27 f->destroy = destroy; 28 return f; 29 } 30 31 void 32 freereqpool(Reqpool *p) 33 { 34 freemap(p->map, (void(*)(void*))p->destroy); 35 free(p); 36 } 37 38 Req* 39 allocreq(Reqpool *pool, ulong tag) 40 { 41 Req *r; 42 43 r = emalloc9p(sizeof *r); 44 r->tag = tag; 45 r->pool = pool; 46 47 increqref(r); 48 increqref(r); 49 if(caninsertkey(pool->map, tag, r) == 0){ 50 closereq(r); 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->afid) 81 closefid(r->afid); 82 if(r->oldreq) 83 closereq(r->oldreq); 84 if(r->nflush) 85 fprint(2, "closereq: flushes remaining\n"); 86 free(r->flush); 87 switch(r->ifcall.type){ 88 case Tstat: 89 free(r->ofcall.stat); 90 free(r->d.name); 91 free(r->d.uid); 92 free(r->d.gid); 93 free(r->d.muid); 94 break; 95 } 96 if(r->pool->destroy) 97 r->pool->destroy(r); 98 free(r->buf); 99 free(r->rbuf); 100 free(r); 101 } 102 } 103 104 Req* 105 removereq(Reqpool *pool, ulong tag) 106 { 107 if(chatty9p > 1) 108 fprint(2, "removereq %lud\n", tag); 109 return deletekey(pool->map, tag); 110 }