X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=ucw%2Frespool.h;h=2c312cffd9e2912f0bff702b7403c7895ccfe1f1;hb=623185a65b8870abb82cd0dd8547a1aa4fc1f535;hp=9764f12948bb0c5a7dada6ddbe855f7e0e1efcbc;hpb=a9f62b4537e7851d50295112c3e89b70ff65b6f3;p=libucw.git diff --git a/ucw/respool.h b/ucw/respool.h index 9764f129..2c312cff 100644 --- a/ucw/respool.h +++ b/ucw/respool.h @@ -7,55 +7,66 @@ * of the GNU Lesser General Public License. */ -/* - * FIXME: - * - check other candidates for resourcification - * - respool as a resource in another respool? - * - unit tests - * - automatic freeing of trans pool on thread exit - */ - #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 }; -struct res_class { - const char *name; - void (*detach)(struct resource *r); - void (*free)(struct resource *r); - void (*dump)(struct resource *r); - uns res_size; // Size of the resource structure (0=default) +/** 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); -void rp_detach(struct respool *rp); -void rp_dump(struct respool *rp); -static inline struct respool * -rp_current(void) +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; // May be NULL + return ucwlib_thread_context()->current_respool; } -static inline struct respool * -rp_switch(struct respool *rp) +/** + * 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; @@ -64,13 +75,64 @@ rp_switch(struct respool *rp) } struct resource *res_alloc(const struct res_class *rc) LIKE_MALLOC; // Returns NULL if there is no pool active -void res_drop(struct resource *r); + +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 + * + * A resource class describes how to handle a particular type of resources. + * Most importantly, it defines a set of 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. However, the resource itself is kept. **/ void res_detach(struct resource *r); -void res_free(struct resource *r); -void res_dump(struct resource *r); -static inline struct resource * // Returns NULL if there is no pool active -res_new(const struct res_class *rc, void *priv) +/** + * Unlinks a resource from a pool and releases its meta-data. Unlike @res_detach(), + * it does not invoke any callbacks. + **/ +void res_drop(struct resource *r); + +/** + * Creates a new resource of the specific class, setting its private data to @priv. + * Returns NULL if there is no resource pool active. + **/ +static inline struct resource *res_new(const struct res_class *rc, void *priv) { struct resource *r = res_alloc(rc); if (r) @@ -81,12 +143,21 @@ res_new(const struct res_class *rc, void *priv) return r; } -/* Various special types of resources */ +/*** + * === Pre-defined resource classes + ***/ + +struct resource *res_for_fd(int fd); /** Creates a resource that closes a given file descriptor. **/ -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(). **/ -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); +/** + * 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); #endif