X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;ds=inline;f=ucw%2Frespool.c;h=64f9a2fc643f14abcbf7d85edbabdb8643aba8a2;hb=31316f76dd68a03b803f51931d6e1fff2c60c5d1;hp=d596a7ae3c2c61f8ef4f7693a683c68880a1b363;hpb=aeb6304585a714ebff73955095d9b49863ebb199;p=libucw.git diff --git a/ucw/respool.c b/ucw/respool.c index d596a7ae..64f9a2fc 100644 --- a/ucw/respool.c +++ b/ucw/respool.c @@ -1,7 +1,7 @@ /* * The UCW Library -- Resource Pools * - * (c) 2008 Martin Mares + * (c) 2008--2011 Martin Mares * * This software may be freely distributed and used according to the terms * of the GNU Lesser General Public License. @@ -27,9 +27,21 @@ rp_new(const char *name, struct mempool *mp) rp = xmalloc_zero(sizeof(*rp)); clist_init(&rp->resources); rp->name = name; + rp->default_res_flags = RES_FLAG_TEMP; return rp; } +static void +rp_free(struct respool *rp) +{ + if (rp->subpool_of) + res_detach(rp->subpool_of); + if (!rp->mpool) + xfree(rp); + if (rp_current() == rp) + rp_switch(NULL); +} + void rp_delete(struct respool *rp) { @@ -39,31 +51,61 @@ rp_delete(struct respool *rp) ASSERT(r->rpool == rp); res_free(r); } - if (!rp->mpool) - xfree(rp); - if (rp_current() == rp) - rp_switch(NULL); + rp_free(rp); +} + +void +rp_detach(struct respool *rp) +{ + struct resource *r; + while (r = clist_head(&rp->resources)) + { + ASSERT(r->rpool == rp); + res_detach(r); + } + rp_free(rp); +} + +void +rp_commit(struct respool *rp) +{ + struct resource *r; + while (r = clist_head(&rp->resources)) + { + ASSERT(r->rpool == rp); + if (r->flags & RES_FLAG_TEMP) + res_free(r); + else + res_detach(r); + } + rp_free(rp); } void -rp_dump(struct respool *rp) +rp_dump(struct respool *rp, uns indent) { - printf("Resource pool %s at %p (%s):\n", (rp->name ? : "(noname)"), rp, (rp->mpool ? "mempool-based" : "freestanding")); + printf("%*sResource pool %s at %p (%s)%s:\n", + indent, "", + (rp->name ? : "(noname)"), + rp, + (rp->mpool ? "mempool-based" : "freestanding"), + (rp->subpool_of ? " (subpool)" : "") + ); CLIST_FOR_EACH(struct resource *, r, rp->resources) - res_dump(r); + res_dump(r, indent+4); } struct resource * res_alloc(const struct res_class *rc) { struct respool *rp = rp_current(); - if (!rp) - return NULL; + ASSERT(rp); uns size = (rc->res_size ? : sizeof(struct resource)); struct resource *r = (rp->mpool ? mp_alloc_fast(rp->mpool, size) : xmalloc(size)); r->rpool = rp; clist_add_tail(&rp->resources, &r->n); + r->flags = rp->default_res_flags; return r; } @@ -78,6 +120,8 @@ res_drop(struct resource *r) void res_detach(struct resource *r) { + if (!r) + return; if (r->rclass->detach) r->rclass->detach(r); res_drop(r); @@ -86,18 +130,21 @@ res_detach(struct resource *r) void res_free(struct resource *r) { + if (!r) + return; if (r->rclass->free) r->rclass->free(r); res_drop(r); } void -res_dump(struct resource *r) +res_dump(struct resource *r, uns indent) { - printf("\t%p %s", r, r->rclass->name); + printf("%*s%p %s %s", indent, "", r, ((r->flags & RES_FLAG_TEMP) ? "TEMP" : "PERM"), r->rclass->name); if (r->rclass->dump) - r->rclass->dump(r); - putchar('\n'); + r->rclass->dump(r, indent+4); + else + putchar('\n'); } #ifdef TEST @@ -110,7 +157,7 @@ int main(void) struct respool *rp = rp_new("test", NULL); rp_switch(rp); struct fastbuf *f = bfdopen_shared(1, 0); - rp_dump(rp); + rp_dump(rp, 0); bputsn(f, "Hello, all worlds!"); bclose(f); rp_delete(rp);