]> mj.ucw.cz Git - libucw.git/blob - ucw/respool.c
31cfc58a8272cb4bb88eb6fc6d7793a30d6e88ad
[libucw.git] / ucw / respool.c
1 /*
2  *      The UCW Library -- Resource Pools
3  *
4  *      (c) 2008 Martin Mares <mj@ucw.cz>
5  *
6  *      This software may be freely distributed and used according to the terms
7  *      of the GNU Lesser General Public License.
8  */
9
10 #include "ucw/lib.h"
11 #include "ucw/respool.h"
12 #include "ucw/mempool.h"
13
14 #include <stdio.h>
15
16 struct respool *
17 rp_new(const char *name, struct mempool *mp)
18 {
19   struct respool *rp;
20
21   if (mp)
22     {
23       rp = mp_alloc_zero(mp, sizeof(*rp));
24       rp->mpool = mp;
25     }
26   else
27     rp = xmalloc_zero(sizeof(*rp));
28   clist_init(&rp->resources);
29   rp->name = name;
30   return rp;
31 }
32
33 static void
34 rp_free(struct respool *rp)
35 {
36   if (rp->subpool_of)
37     res_detach(rp->subpool_of);
38   if (!rp->mpool)
39     xfree(rp);
40   if (rp_current() == rp)
41     rp_switch(NULL);
42 }
43
44 void
45 rp_delete(struct respool *rp)
46 {
47   struct resource *r;
48   while (r = clist_tail(&rp->resources))
49     {
50       ASSERT(r->rpool == rp);
51       res_free(r);
52     }
53   rp_free(rp);
54 }
55
56 void
57 rp_detach(struct respool *rp)
58 {
59   struct resource *r;
60   while (r = clist_head(&rp->resources))
61     {
62       ASSERT(r->rpool == rp);
63       res_detach(r);
64     }
65   rp_free(rp);
66 }
67
68 void
69 rp_dump(struct respool *rp, uns indent)
70 {
71   printf("%*sResource pool %s at %p (%s)%s:\n",
72          indent, "",
73          (rp->name ? : "(noname)"),
74          rp,
75          (rp->mpool ? "mempool-based" : "freestanding"),
76          (rp->subpool_of ? " (subpool)" : "")
77          );
78   CLIST_FOR_EACH(struct resource *, r, rp->resources)
79     res_dump(r, indent+4);
80 }
81
82 struct resource *
83 res_alloc(const struct res_class *rc)
84 {
85   struct respool *rp = rp_current();
86   if (!rp)
87     return NULL;
88
89   uns size = (rc->res_size ? : sizeof(struct resource));
90   struct resource *r = (rp->mpool ? mp_alloc_fast(rp->mpool, size) : xmalloc(size));
91   r->rpool = rp;
92   clist_add_tail(&rp->resources, &r->n);
93   return r;
94 }
95
96 void
97 res_drop(struct resource *r)
98 {
99   clist_remove(&r->n);
100   if (!r->rpool->mpool)
101     xfree(r);
102 }
103
104 void
105 res_detach(struct resource *r)
106 {
107   if (r->rclass->detach)
108     r->rclass->detach(r);
109   res_drop(r);
110 }
111
112 void
113 res_free(struct resource *r)
114 {
115   if (r->rclass->free)
116     r->rclass->free(r);
117   res_drop(r);
118 }
119
120 void
121 res_dump(struct resource *r, uns indent)
122 {
123   printf("%*s%p %s", indent, "", r, r->rclass->name);
124   if (r->rclass->dump)
125     r->rclass->dump(r, indent+4);
126   else
127     putchar('\n');
128 }
129
130 #ifdef TEST
131
132 #include "ucw/fastbuf.h"
133
134 int main(void)
135 {
136   // struct mempool *mp = mp_new(4096);
137   struct respool *rp = rp_new("test", NULL);
138   rp_switch(rp);
139   struct fastbuf *f = bfdopen_shared(1, 0);
140   rp_dump(rp, 0);
141   bputsn(f, "Hello, all worlds!");
142   bclose(f);
143   rp_delete(rp);
144   return 0;
145 }
146
147 #endif