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 \
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
- <<exc,Exceptions>>
- <<excnames,Exception names>>
-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
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]]
-----------------------------------
#include "ucw/lib.h"
#include "ucw/fastbuf.h"
-#include "ucw/respool.h"
+#include "ucw/resource.h"
#include "ucw/trans.h"
#include "ucw/stkstring.h"
*/
#include "ucw/lib.h"
-#include "ucw/respool.h"
+#include "ucw/resource.h"
#include "ucw/eltpool.h"
#include <stdio.h>
*/
#include "ucw/lib.h"
-#include "ucw/respool.h"
+#include "ucw/resource.h"
#include <stdio.h>
#include <unistd.h>
*/
#include "ucw/lib.h"
-#include "ucw/respool.h"
+#include "ucw/resource.h"
#include <stdio.h>
#include <stdlib.h>
*/
#include "ucw/lib.h"
-#include "ucw/respool.h"
+#include "ucw/resource.h"
#include "ucw/mempool.h"
#include <stdio.h>
*/
#include "ucw/lib.h"
-#include "ucw/respool.h"
+#include "ucw/resource.h"
#include <stdio.h>
--- /dev/null
+/*
+ * The UCW Library -- Resource Pools
+ *
+ * (c) 2008--2011 Martin Mares <mj@ucw.cz>
+ *
+ * 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 <stdio.h>
+
+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
--- /dev/null
+/*
+ * The UCW Library -- Resource Pools
+ *
+ * (c) 2008--2011 Martin Mares <mj@ucw.cz>
+ *
+ * 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 <<mempool:,memory pool>>. **/
+
+struct eltpool;
+struct resource *res_eltpool(struct eltpool *ep); /** Creates a resource for the specified <<eltpool:,element pool>>. **/
+
+#endif
+++ /dev/null
-/*
- * The UCW Library -- Resource Pools
- *
- * (c) 2008--2011 Martin Mares <mj@ucw.cz>
- *
- * 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 <stdio.h>
-
-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
+++ /dev/null
-/*
- * The UCW Library -- Resource Pools
- *
- * (c) 2008--2011 Martin Mares <mj@ucw.cz>
- *
- * 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 <<mempool:,memory pool>>. **/
-
-struct eltpool;
-struct resource *res_eltpool(struct eltpool *ep); /** Creates a resource for the specified <<eltpool:,element pool>>. **/
-
-#endif
#include "ucw/lib.h"
#include "ucw/trans.h"
-#include "ucw/respool.h"
+#include "ucw/resource.h"
#include "ucw/mempool.h"
#include <stdio.h>