From: Martin Mares Date: Tue, 19 Apr 2011 12:32:05 +0000 (+0200) Subject: Implemented temporary resources X-Git-Tag: v5.0~74^2~16 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=623185a65b8870abb82cd0dd8547a1aa4fc1f535;p=libucw.git Implemented temporary resources --- diff --git a/ucw/doc/trans.txt b/ucw/doc/trans.txt index d2c10df3..349055f7 100644 --- a/ucw/doc/trans.txt +++ b/ucw/doc/trans.txt @@ -22,6 +22,14 @@ A resource can be also freed separately (which unlinks it from the pool), or *detached* from the pool (which keeps the real resource, but forgets its meta-data, so the resource is no longer tracked). +In many cases, a combination of both methods is needed: some resources +are marked as temporary, while some others are permanent. When the +an operation is completed successfully (and @rp_commit() is called), +all temporary resources are freed and the permanent ones detached. +When the operation fails, @rp_delete() deletes all resources. By default, +all resources are created as temporary. You can make a resource permanent +by calling @res_permanent(), or change the default in `resource->default_res_flags`. + For each thread, LibUCW remembers the currently active resource pool. One pool can be used for at most one thread at a time. All functions which create resources do so in the active pool. All other functions diff --git a/ucw/respool.c b/ucw/respool.c index 31cfc58a..a4978fdf 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,6 +27,7 @@ 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; } @@ -65,6 +66,21 @@ rp_detach(struct respool *rp) 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, uns indent) { @@ -90,6 +106,7 @@ res_alloc(const struct res_class *rc) 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; } @@ -120,7 +137,7 @@ res_free(struct resource *r) void res_dump(struct resource *r, uns indent) { - printf("%*s%p %s", indent, "", 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, indent+4); else diff --git a/ucw/respool.h b/ucw/respool.h index a12552ab..2c312cff 100644 --- a/ucw/respool.h +++ b/ucw/respool.h @@ -23,6 +23,7 @@ struct respool { const char *name; struct mempool *mpool; // If set, resources are allocated from the mempool, otherwise by xmalloc() struct resource *subpool_of; + uns default_res_flags; // RES_FLAG_xxx for newly allocated resources }; /** @@ -33,11 +34,17 @@ struct respool { struct resource { cnode n; struct respool *rpool; + uns flags; // RES_FLAG_xxx const struct res_class *rclass; void *priv; // Private to the class // More data specific for the particular class can follow }; +/** Resource flags **/ +enum resource_flags { + RES_FLAG_TEMP = 1, // Resource is temporary +}; + /** * Creates a new resource pool. If a memory pool is given, meta-data of all resources * will be allocated from this pool. Otherwise, they will be malloc'ed. @@ -46,6 +53,7 @@ struct respool *rp_new(const char *name, struct mempool *mp); void rp_delete(struct respool *rp); /** Deletes a resource pool, freeing all resources. **/ void rp_detach(struct respool *rp); /** Deletes a resource pool, detaching all resources. **/ +void rp_commit(struct respool *rp); /** Deletes a resource pool. Temporary resources are freed, stable resources are detached. **/ void rp_dump(struct respool *rp, uns indent); /** Prints out a debugging dump of a pool to stdout. **/ /** Returns a pointer to the currently active resource pool or NULL, if none exists. **/ @@ -71,6 +79,18 @@ struct resource *res_alloc(const struct res_class *rc) LIKE_MALLOC; // Returns N void res_dump(struct resource *r, uns indent); /** Prints out a debugging dump of the resource to stdout. **/ void res_free(struct resource *r); /** Frees a resource, unlinking it from its pool. **/ +/** Marks a resource as temporary (sets @RES_FLAG_TEMP). **/ +static inline void res_temporary(struct resource *r) +{ + r->flags |= RES_FLAG_TEMP; +} + +/** Marks a resource as permanent (clears @RES_FLAG_TEMP). **/ +static inline void res_permanent(struct resource *r) +{ + r->flags &= RES_FLAG_TEMP; +} + /*** * === Resource classes *