]> mj.ucw.cz Git - libucw.git/blobdiff - ucw/respool.c
Resources: Added mempool class
[libucw.git] / ucw / respool.c
index 9a747cd40d72be1fd3f61105b74f783bdd98d0d5..64f9a2fc643f14abcbf7d85edbabdb8643aba8a2 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *     The UCW Library -- Resource Pools
  *
 /*
  *     The UCW Library -- Resource Pools
  *
- *     (c) 2008 Martin Mares <mj@ucw.cz>
+ *     (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.
  *
  *     This software may be freely distributed and used according to the terms
  *     of the GNU Lesser General Public License.
@@ -27,41 +27,90 @@ rp_new(const char *name, struct mempool *mp)
     rp = xmalloc_zero(sizeof(*rp));
   clist_init(&rp->resources);
   rp->name = name;
     rp = xmalloc_zero(sizeof(*rp));
   clist_init(&rp->resources);
   rp->name = name;
+  rp->default_res_flags = RES_FLAG_TEMP;
   return rp;
 }
 
   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))
 void
 rp_delete(struct respool *rp)
 {
   struct resource *r;
   while (r = clist_tail(&rp->resources))
-    res_free(r);
-  if (!rp->mpool)
-    xfree(rp);
+    {
+      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
 }
 
 void
-rp_dump(struct respool *rp)
+rp_commit(struct respool *rp)
 {
 {
-  printf("Resource pool %s at %p (%s):\n", (rp->name ? : "(noname)"), rp, (rp->mpool ? "mempool-based" : "freestanding"));
+  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)
   CLIST_FOR_EACH(struct resource *, r, rp->resources)
-    res_dump(r);
+    res_dump(r, indent+4);
 }
 
 struct resource *
 }
 
 struct resource *
-res_alloc(void)
+res_alloc(const struct res_class *rc)
 {
   struct respool *rp = rp_current();
 {
   struct respool *rp = rp_current();
-  if (!rp)
-    return NULL;
+  ASSERT(rp);
 
 
-  struct resource *r = (rp->mpool ? mp_alloc_fast(rp->mpool, sizeof(*r)) : xmalloc(sizeof(*r)));
+  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);
   clist_add_tail(&rp->resources, &r->n);
+  r->flags = rp->default_res_flags;
   return r;
 }
 
   return r;
 }
 
-static inline void
-res_do_free(struct resource *r)
+void
+res_drop(struct resource *r)
 {
   clist_remove(&r->n);
   if (!r->rpool->mpool)
 {
   clist_remove(&r->n);
   if (!r->rpool->mpool)
@@ -71,34 +120,47 @@ res_do_free(struct resource *r)
 void
 res_detach(struct resource *r)
 {
 void
 res_detach(struct resource *r)
 {
+  if (!r)
+    return;
   if (r->rclass->detach)
     r->rclass->detach(r);
   if (r->rclass->detach)
     r->rclass->detach(r);
-  res_do_free(r);
+  res_drop(r);
 }
 
 void
 res_free(struct resource *r)
 {
 }
 
 void
 res_free(struct resource *r)
 {
+  if (!r)
+    return;
   if (r->rclass->free)
     r->rclass->free(r);
   if (r->rclass->free)
     r->rclass->free(r);
-  res_do_free(r);
+  res_drop(r);
 }
 
 void
 }
 
 void
-res_dump(struct resource *r)
+res_dump(struct resource *r, uns indent)
 {
 {
-  printf("\t%p %s", 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)
   if (r->rclass->dump)
-    r->rclass->dump(r);
-  putchar('\n');
+    r->rclass->dump(r, indent+4);
+  else
+    putchar('\n');
 }
 
 #ifdef TEST
 
 }
 
 #ifdef TEST
 
+#include "ucw/fastbuf.h"
+
 int main(void)
 {
 int main(void)
 {
+  // struct mempool *mp = mp_new(4096);
   struct respool *rp = rp_new("test", NULL);
   struct respool *rp = rp_new("test", NULL);
-  rp_dump(rp);
+  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;
 }
 
   return 0;
 }