plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

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 }