From: Martin Mares Date: Tue, 19 Apr 2011 13:47:34 +0000 (+0200) Subject: Resources: Renamed respool.* -> resource.* X-Git-Tag: v5.0~74^2~2 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=a594d6320ee28c15332b4c0f240caab7ea8f857a;p=libucw.git Resources: Renamed respool.* -> resource.* --- diff --git a/ucw/Makefile b/ucw/Makefile index e97c2832..15e56870 100644 --- a/ucw/Makefile +++ b/ucw/Makefile @@ -34,7 +34,7 @@ LIBUCW_MODS= \ bbuf gary \ getopt \ strtonum \ - respool trans res-fd res-mem res-subpool res-mempool res-eltpool + resource trans res-fd res-mem res-subpool res-mempool res-eltpool LIBUCW_MAIN_INCLUDES= \ lib.h log.h threads.h \ @@ -61,7 +61,7 @@ LIBUCW_MAIN_INCLUDES= \ kmp.h kmp-search.h binsearch.h \ partmap.h \ strtonum.h \ - respool.h trans.h + resource.h trans.h ifdef CONFIG_UCW_THREADS # Some modules require threading diff --git a/ucw/doc/trans.txt b/ucw/doc/trans.txt index 152c6dad..df3c8c0b 100644 --- a/ucw/doc/trans.txt +++ b/ucw/doc/trans.txt @@ -15,8 +15,8 @@ within the transaction. - <> - <> -Resource pools: ucw/respool.h [[respools]] ------------------------------------------- +Resource pools: ucw/resource.h [[respools]] +------------------------------------------- A resource pool contains a stack of resources. When a new resource is created, it is pushed onto the stack. When freeing the pool, the @@ -40,7 +40,7 @@ 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 operating on resources work on both active and in-active pools. -!!ucw/respool.h +!!ucw/resource.h Transactions: ucw/trans.h [[trans]] ----------------------------------- diff --git a/ucw/fastbuf.c b/ucw/fastbuf.c index 3c0481b3..a66d712b 100644 --- a/ucw/fastbuf.c +++ b/ucw/fastbuf.c @@ -11,7 +11,7 @@ #include "ucw/lib.h" #include "ucw/fastbuf.h" -#include "ucw/respool.h" +#include "ucw/resource.h" #include "ucw/trans.h" #include "ucw/stkstring.h" diff --git a/ucw/res-eltpool.c b/ucw/res-eltpool.c index b6027aed..b5480bfd 100644 --- a/ucw/res-eltpool.c +++ b/ucw/res-eltpool.c @@ -8,7 +8,7 @@ */ #include "ucw/lib.h" -#include "ucw/respool.h" +#include "ucw/resource.h" #include "ucw/eltpool.h" #include diff --git a/ucw/res-fd.c b/ucw/res-fd.c index ab04b8e7..99d2dfcf 100644 --- a/ucw/res-fd.c +++ b/ucw/res-fd.c @@ -8,7 +8,7 @@ */ #include "ucw/lib.h" -#include "ucw/respool.h" +#include "ucw/resource.h" #include #include diff --git a/ucw/res-mem.c b/ucw/res-mem.c index 16aba180..a6b425f1 100644 --- a/ucw/res-mem.c +++ b/ucw/res-mem.c @@ -8,7 +8,7 @@ */ #include "ucw/lib.h" -#include "ucw/respool.h" +#include "ucw/resource.h" #include #include diff --git a/ucw/res-mempool.c b/ucw/res-mempool.c index 51a85c53..74e5fa63 100644 --- a/ucw/res-mempool.c +++ b/ucw/res-mempool.c @@ -8,7 +8,7 @@ */ #include "ucw/lib.h" -#include "ucw/respool.h" +#include "ucw/resource.h" #include "ucw/mempool.h" #include diff --git a/ucw/res-subpool.c b/ucw/res-subpool.c index e224ae2c..c2ecbd09 100644 --- a/ucw/res-subpool.c +++ b/ucw/res-subpool.c @@ -8,7 +8,7 @@ */ #include "ucw/lib.h" -#include "ucw/respool.h" +#include "ucw/resource.h" #include diff --git a/ucw/resource.c b/ucw/resource.c new file mode 100644 index 00000000..c4bed3ad --- /dev/null +++ b/ucw/resource.c @@ -0,0 +1,167 @@ +/* + * The UCW Library -- Resource Pools + * + * (c) 2008--2011 Martin Mares + * + * This software may be freely distributed and used according to the terms + * of the GNU Lesser General Public License. + */ + +#include "ucw/lib.h" +#include "ucw/resource.h" +#include "ucw/mempool.h" + +#include + +struct respool * +rp_new(const char *name, struct mempool *mp) +{ + struct respool *rp; + + if (mp) + { + rp = mp_alloc_zero(mp, sizeof(*rp)); + rp->mpool = mp; + } + else + 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)) + { + 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_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) +{ + 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, indent+4); +} + +struct resource * +res_alloc(const struct res_class *rc) +{ + struct respool *rp = rp_current(); + 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; +} + +void +res_drop(struct resource *r) +{ + clist_remove(&r->n); + if (!r->rpool->mpool) + xfree(r); +} + +void +res_detach(struct resource *r) +{ + if (!r) + return; + if (r->rclass->detach) + r->rclass->detach(r); + res_drop(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, uns indent) +{ + 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 + 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_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; +} + +#endif diff --git a/ucw/resource.h b/ucw/resource.h new file mode 100644 index 00000000..d2a415c3 --- /dev/null +++ b/ucw/resource.h @@ -0,0 +1,175 @@ +/* + * The UCW Library -- Resource Pools + * + * (c) 2008--2011 Martin Mares + * + * This software may be freely distributed and used according to the terms + * of the GNU Lesser General Public License. + */ + +#ifndef _UCW_RESPOOL_H +#define _UCW_RESPOOL_H + +#include "ucw/clists.h" +#include "ucw/threads.h" + +/** + * A resource pool. It contains a name of the pool (which is printed + * in all debugging dumps, otherwise it is not used) and a bunch of + * fields for internal use. + **/ +struct respool { + clist resources; + 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 +}; + +/** + * Each resource is represented by this structure. It is linked to a resource + * pool it belongs to. It contains a pointer to a resource class (which describes how to + * handle the resource) and data private to the resource class. + **/ +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. + **/ +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. **/ +static inline struct respool *rp_current(void) +{ + return ucwlib_thread_context()->current_respool; +} + +/** + * Makes the given resource pool active; returns a pointer to the previously active pool + * or NULL, if there was none. Calling with @rp equal to NULL deactivates the pool. + **/ +static inline struct respool *rp_switch(struct respool *rp) +{ + struct ucwlib_context *ctx = ucwlib_thread_context(); + struct respool *orp = ctx->current_respool; + ctx->current_respool = rp; + return orp; +} + +struct resource *res_alloc(const struct res_class *rc) LIKE_MALLOC; // Returns NULL if there is no pool active + +void res_dump(struct resource *r, uns indent); /** Prints out a debugging dump of the resource to stdout. **/ + +/** + * Frees a resource, unlinking it from its pool. + * When called with a NULL pointer, it does nothing, but safely. + **/ +void res_free(struct resource *r); + +/** + * Unlinks a resource from a pool and releases its meta-data. However, the resource itself is kept. + * When called with a NULL pointer, it does nothing, but safely. + **/ +void res_detach(struct resource *r); + +/** 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 + * + * A resource class describes how to handle a particular type of resources. + * Most importantly, it defines a set of (optional) callbacks for performing operations + * on the resources: + * + * * dump() should print a description of the resource used for debugging + * to the standard output. The description should end with a newline character + * and in case of a multi-line description, the subsequent lines should be + * indented by @indent spaces. + * * free() frees the resource; the struct resource is freed automatically afterwards. + * * detach() breaks the link between the struct resource and the real resource; + * the struct resource is freed automatically afterwards, while the resource + * continues to live. + * + * The following functions are intended for use by the resource classes only. + ***/ + +/** The structure describing a resource class. **/ +struct res_class { + const char *name; // The name of the class (included in debugging dumps) + void (*detach)(struct resource *r); // The callbacks + void (*free)(struct resource *r); + void (*dump)(struct resource *r, uns indent); + uns res_size; // Size of the resource structure (0=default) +}; + +/** + * Unlinks a resource from a pool and releases its meta-data. Unlike @res_detach(), + * it does not invoke any callbacks. The caller must make sure that no references to + * the meta-data remain, so this is generally safe only inside resource class code. + **/ +void res_drop(struct resource *r); + +/** + * Creates a new resource of the specific class, setting its private data to @priv. + * Dies if no resource pool is active. + **/ +static inline struct resource *res_new(const struct res_class *rc, void *priv) +{ + struct resource *r = res_alloc(rc); + r->rclass = rc; + r->priv = priv; + return r; +} + +/*** + * === Pre-defined resource classes + ***/ + +struct resource *res_for_fd(int fd); /** Creates a resource that closes a given file descriptor. **/ + +void *res_malloc(size_t size, struct resource **ptr) LIKE_MALLOC; /** Allocates memory and creates a resource for it. **/ +void *res_malloc_zero(size_t size, struct resource **ptr) LIKE_MALLOC; /** Allocates zero-initialized memory and creates a resource for it. **/ +void *res_realloc(struct resource *res, size_t size); /** Re-allocates memory obtained by @res_malloc() or @res_malloc_zero(). **/ + +/** + * Converts the resource pool @rp to a resource inside the current resource pool (i.e., its sub-pool). + * You can delete the sub-pool either by freeing this resource, or by calling + * @rp_delete() on it, which removes the resource automatically. + **/ +struct resource *res_subpool(struct respool *rp); + +struct mempool; +struct resource *res_mempool(struct mempool *mp); /** Creates a resource for the specified <>. **/ + +struct eltpool; +struct resource *res_eltpool(struct eltpool *ep); /** Creates a resource for the specified <>. **/ + +#endif diff --git a/ucw/respool.c b/ucw/respool.c deleted file mode 100644 index 64f9a2fc..00000000 --- a/ucw/respool.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * The UCW Library -- Resource Pools - * - * (c) 2008--2011 Martin Mares - * - * This software may be freely distributed and used according to the terms - * of the GNU Lesser General Public License. - */ - -#include "ucw/lib.h" -#include "ucw/respool.h" -#include "ucw/mempool.h" - -#include - -struct respool * -rp_new(const char *name, struct mempool *mp) -{ - struct respool *rp; - - if (mp) - { - rp = mp_alloc_zero(mp, sizeof(*rp)); - rp->mpool = mp; - } - else - 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)) - { - 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_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) -{ - 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, indent+4); -} - -struct resource * -res_alloc(const struct res_class *rc) -{ - struct respool *rp = rp_current(); - 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; -} - -void -res_drop(struct resource *r) -{ - clist_remove(&r->n); - if (!r->rpool->mpool) - xfree(r); -} - -void -res_detach(struct resource *r) -{ - if (!r) - return; - if (r->rclass->detach) - r->rclass->detach(r); - res_drop(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, uns indent) -{ - 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 - 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_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; -} - -#endif diff --git a/ucw/respool.h b/ucw/respool.h deleted file mode 100644 index d2a415c3..00000000 --- a/ucw/respool.h +++ /dev/null @@ -1,175 +0,0 @@ -/* - * The UCW Library -- Resource Pools - * - * (c) 2008--2011 Martin Mares - * - * This software may be freely distributed and used according to the terms - * of the GNU Lesser General Public License. - */ - -#ifndef _UCW_RESPOOL_H -#define _UCW_RESPOOL_H - -#include "ucw/clists.h" -#include "ucw/threads.h" - -/** - * A resource pool. It contains a name of the pool (which is printed - * in all debugging dumps, otherwise it is not used) and a bunch of - * fields for internal use. - **/ -struct respool { - clist resources; - 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 -}; - -/** - * Each resource is represented by this structure. It is linked to a resource - * pool it belongs to. It contains a pointer to a resource class (which describes how to - * handle the resource) and data private to the resource class. - **/ -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. - **/ -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. **/ -static inline struct respool *rp_current(void) -{ - return ucwlib_thread_context()->current_respool; -} - -/** - * Makes the given resource pool active; returns a pointer to the previously active pool - * or NULL, if there was none. Calling with @rp equal to NULL deactivates the pool. - **/ -static inline struct respool *rp_switch(struct respool *rp) -{ - struct ucwlib_context *ctx = ucwlib_thread_context(); - struct respool *orp = ctx->current_respool; - ctx->current_respool = rp; - return orp; -} - -struct resource *res_alloc(const struct res_class *rc) LIKE_MALLOC; // Returns NULL if there is no pool active - -void res_dump(struct resource *r, uns indent); /** Prints out a debugging dump of the resource to stdout. **/ - -/** - * Frees a resource, unlinking it from its pool. - * When called with a NULL pointer, it does nothing, but safely. - **/ -void res_free(struct resource *r); - -/** - * Unlinks a resource from a pool and releases its meta-data. However, the resource itself is kept. - * When called with a NULL pointer, it does nothing, but safely. - **/ -void res_detach(struct resource *r); - -/** 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 - * - * A resource class describes how to handle a particular type of resources. - * Most importantly, it defines a set of (optional) callbacks for performing operations - * on the resources: - * - * * dump() should print a description of the resource used for debugging - * to the standard output. The description should end with a newline character - * and in case of a multi-line description, the subsequent lines should be - * indented by @indent spaces. - * * free() frees the resource; the struct resource is freed automatically afterwards. - * * detach() breaks the link between the struct resource and the real resource; - * the struct resource is freed automatically afterwards, while the resource - * continues to live. - * - * The following functions are intended for use by the resource classes only. - ***/ - -/** The structure describing a resource class. **/ -struct res_class { - const char *name; // The name of the class (included in debugging dumps) - void (*detach)(struct resource *r); // The callbacks - void (*free)(struct resource *r); - void (*dump)(struct resource *r, uns indent); - uns res_size; // Size of the resource structure (0=default) -}; - -/** - * Unlinks a resource from a pool and releases its meta-data. Unlike @res_detach(), - * it does not invoke any callbacks. The caller must make sure that no references to - * the meta-data remain, so this is generally safe only inside resource class code. - **/ -void res_drop(struct resource *r); - -/** - * Creates a new resource of the specific class, setting its private data to @priv. - * Dies if no resource pool is active. - **/ -static inline struct resource *res_new(const struct res_class *rc, void *priv) -{ - struct resource *r = res_alloc(rc); - r->rclass = rc; - r->priv = priv; - return r; -} - -/*** - * === Pre-defined resource classes - ***/ - -struct resource *res_for_fd(int fd); /** Creates a resource that closes a given file descriptor. **/ - -void *res_malloc(size_t size, struct resource **ptr) LIKE_MALLOC; /** Allocates memory and creates a resource for it. **/ -void *res_malloc_zero(size_t size, struct resource **ptr) LIKE_MALLOC; /** Allocates zero-initialized memory and creates a resource for it. **/ -void *res_realloc(struct resource *res, size_t size); /** Re-allocates memory obtained by @res_malloc() or @res_malloc_zero(). **/ - -/** - * Converts the resource pool @rp to a resource inside the current resource pool (i.e., its sub-pool). - * You can delete the sub-pool either by freeing this resource, or by calling - * @rp_delete() on it, which removes the resource automatically. - **/ -struct resource *res_subpool(struct respool *rp); - -struct mempool; -struct resource *res_mempool(struct mempool *mp); /** Creates a resource for the specified <>. **/ - -struct eltpool; -struct resource *res_eltpool(struct eltpool *ep); /** Creates a resource for the specified <>. **/ - -#endif diff --git a/ucw/trans.c b/ucw/trans.c index 6fc9e8eb..4f04dac4 100644 --- a/ucw/trans.c +++ b/ucw/trans.c @@ -11,7 +11,7 @@ #include "ucw/lib.h" #include "ucw/trans.h" -#include "ucw/respool.h" +#include "ucw/resource.h" #include "ucw/mempool.h" #include