+/* -*-c-*-
+ *
+ * Resource pool handling
+ *
+ * (c) 2000 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------*
+ *
+ * This file is part of the mLib utilities library.
+ *
+ * mLib is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * mLib is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with mLib; if not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#ifndef MLIB_POOL_H
+#define MLIB_POOL_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/*----- Header files ------------------------------------------------------*/
+
+#include <stdio.h>
+
+#ifndef MLIB_ARENA_H
+# include "arena.h"
+#endif
+
+#ifndef MLIB_SUB_H
+# include "sub.h"
+#endif
+
+/*----- Data structures ---------------------------------------------------*/
+
+#define POOL_CHUNKSZ 65536
+
+typedef struct pool_chunk {
+ struct pool_chunk *next; /* Next memory chunk in the chain */
+ char *p; /* Free area in this chunk */
+ size_t left; /* Amount of memory left */
+} pool_chunk;
+
+typedef struct pool_resource {
+ struct pool_resource *next; /* Next resource in the chain */
+ void (*destroy)(struct pool_resource */*r*/); /* Destruction function */
+} pool_resource;
+
+typedef struct pool {
+ arena a; /* The arena for allocating memory */
+ pool_chunk *c; /* Pointer to memory chunk list */
+ pool_resource *r; /* Pointer to resource list */
+ arena *pa; /* Arena for real allocation */
+} pool;
+
+typedef struct pool_file {
+ pool_resource r; /* A pool resource record */
+ FILE *fp; /* The actual file handle */
+} pool_file;
+
+/*----- Basic pool management ---------------------------------------------*/
+
+/* --- @pool_alloc@ --- *
+ *
+ * Arguments: @pool *p@ = pool to allocate from
+ * @size_t sz@ = size of block wanted
+ *
+ * Returns: Pointer to the requested block.
+ *
+ * Use: Allocates memory from a resource pool. Memory is never freed
+ * from pools: it is released when the pool is destroyed.
+ */
+
+extern void *pool_alloc(pool */*p*/, size_t /*sz*/);
+
+/* --- @pool_strdup@ --- *
+ *
+ * Arguments: @pool *p@ = pool to allocate from
+ * @const char *s@ = pointer to string
+ *
+ * Returns: A pointer to a copy of the string.
+ *
+ * Use: Allocates a copy of a string.
+ */
+
+extern char *pool_strdup(pool */*p*/, const char */*s*/);
+
+/* --- @pool_create@ --- *
+ *
+ * Arguments: @arena *a@ = pointer to an arena to allocate memory from
+ *
+ * Returns: A newly created resource pool.
+ *
+ * Use: Creates a resource pool which is not a child of any other
+ * resource pool.
+ */
+
+extern pool *pool_create(arena */*a*/);
+
+/* --- @pool_destroy@ --- *
+ *
+ * Arguments: @pool *p@ = pointer to pool to destroy
+ *
+ * Returns: ---
+ *
+ * Use: Destroys a pool, freeing all of the resources within it. If
+ * this is a root pool, its memory will be deallocated; if it's
+ * a subpool, it is emptied and can be used again.
+ */
+
+extern void pool_destroy(pool */*p*/);
+
+/* --- @pool_sub@ --- *
+ *
+ * Arguments: @pool *p@ = pointer to parent pool
+ *
+ * Returns: A new child pool of the parent.
+ *
+ * Use: Creates a subpool. The subpool can either be destroyed on
+ * its own, or will be automatically destroyed at the same time
+ * as the parent.
+ */
+
+extern pool *pool_sub(pool */*p*/);
+
+/* --- @pool_add@ --- *
+ *
+ * Arguments: @pool *p@ = pointer to pool to add the resource to
+ * @pool_resource *r@ = pointer to resource block
+ * @void (*dfn)(pool_resource *r)@ = destruction function
+ *
+ * Returns: ---
+ *
+ * Use: Adds a resource to a pool.
+ */
+
+#define POOL_ADD(p, rr, dfn) do { \
+ pool *_p = (p); \
+ pool_resource *_r = (rr); \
+ _r->next = _p->r; \
+ _r->destroy = dfn; \
+ _p->r = _r; \
+} while (0)
+
+extern void pool_add(pool */*p*/, pool_resource */*r*/,
+ void (*/*dfn*/)(pool_resource */*r*/));
+
+/*----- Various simple resource types -------------------------------------*/
+
+/* --- @pool_fopen@ --- *
+ *
+ * Arguments: @pool *p@ = pointer to a pool
+ * @const char *file@ = name of the file to open
+ * @const char *how@ = string specifying opening parameters
+ *
+ * Returns: A pointer to a pool resource containing an open file handle,
+ * or null if the file open filed.
+ *
+ * Use: Opens a file so that it will be freed again when a pool is
+ * destroyed.
+ */
+
+extern pool_file *pool_fopen(pool */*p*/,
+ const char */*file*/, const char */*how*/);
+
+/* --- @pool_fclose@ --- *
+ *
+ * Arguments: @pool_file *pf@ = pointer to a file resource
+ *
+ * Returns: The response from the @fclose@ function.
+ *
+ * Use: Closes a file. It is not an error to close a file multiple
+ * times.
+ */
+
+extern int pool_fclose(pool_file */*pf*/);
+
+/* --- @pool_subarena@ --- *
+ *
+ * Arguments: @pool *p@ = pointer to the pool
+ *
+ * Returns: A subarena built from the pool's memory allocator.
+ *
+ * Use: Creates a suballocation arena attached to a pool. The arena
+ * and all of its memory will be freed when the pool is
+ * destroyed.
+ */
+
+extern subarena *pool_subarena(pool */*p*/);
+
+/*----- That's all, folks -------------------------------------------------*/
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif