X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=ucw%2Frespool.c;h=64f9a2fc643f14abcbf7d85edbabdb8643aba8a2;hb=bfca2c42bc0e749f8611339568be502f22ac5e9c;hp=9a747cd40d72be1fd3f61105b74f783bdd98d0d5;hpb=847bb5125836ac3c89a9118be60cb077090f4756;p=libucw.git diff --git a/ucw/respool.c b/ucw/respool.c index 9a747cd4..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,41 +27,90 @@ 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) { struct resource *r; while (r = clist_tail(&rp->resources)) - res_free(r); - if (!rp->mpool) - xfree(rp); + { + ASSERT(r->rpool == rp); + res_free(r); + } + 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_dump(struct respool *rp) +rp_commit(struct respool *rp) { - printf("Resource pool %s at %p (%s):\n", (rp->name ? : "(noname)"), rp, (rp->mpool ? "mempool-based" : "freestanding")); + 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, uns indent) +{ + 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(void) +res_alloc(const struct res_class *rc) { struct respool *rp = rp_current(); - if (!rp) - return NULL; + ASSERT(rp); - struct resource *r = (rp->mpool ? mp_alloc_fast(rp->mpool, sizeof(*r)) : xmalloc(sizeof(*r))); + 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; } -static inline void -res_do_free(struct resource *r) +void +res_drop(struct resource *r) { clist_remove(&r->n); if (!r->rpool->mpool) @@ -71,34 +120,47 @@ res_do_free(struct resource *r) void res_detach(struct resource *r) { + if (!r) + return; if (r->rclass->detach) r->rclass->detach(r); - res_do_free(r); + res_drop(r); } void res_free(struct resource *r) { + if (!r) + return; if (r->rclass->free) r->rclass->free(r); - res_do_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 +#include "ucw/fastbuf.h" + int main(void) { + // struct mempool *mp = mp_new(4096); struct respool *rp = rp_new("test", NULL); - rp_dump(rp); + rp_switch(rp); + struct fastbuf *f = bfdopen_shared(1, 0); + rp_dump(rp, 0); + bputsn(f, "Hello, all worlds!"); + bclose(f); + rp_delete(rp); return 0; }