]> mj.ucw.cz Git - libucw.git/blob - ucw/resource.h
e67f9728a14cdddfb9968ed238ba715c68c5c9c1
[libucw.git] / ucw / resource.h
1 /*
2  *      The UCW Library -- Resource Pools
3  *
4  *      (c) 2008--2011 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 #ifndef _UCW_RESPOOL_H
11 #define _UCW_RESPOOL_H
12
13 #include <ucw/clists.h>
14 #include <ucw/threads.h>
15
16 /**
17  * A resource pool. It contains a name of the pool (which is printed
18  * in all debugging dumps, otherwise it is not used) and a bunch of
19  * fields for internal use.
20  **/
21 struct respool {
22   clist resources;
23   const char *name;
24   struct mempool *mpool;                                // If set, resources are allocated from the mempool, otherwise by xmalloc()
25   struct resource *subpool_of;
26   uns default_res_flags;                                // RES_FLAG_xxx for newly allocated resources
27 };
28
29 /**
30  * Each resource is represented by this structure. It is linked to a resource
31  * pool it belongs to. It contains a pointer to a resource class (which describes how to
32  * handle the resource) and data private to the resource class.
33  **/
34 struct resource {
35   cnode n;
36   struct respool *rpool;
37   uns flags;                                            // RES_FLAG_xxx
38   const struct res_class *rclass;
39   void *priv;                                           // Private to the class
40   // More data specific for the particular class can follow
41 };
42
43 /** Resource flags **/
44 enum resource_flags {
45   RES_FLAG_TEMP = 1,                                    // Resource is temporary
46   RES_FLAG_XFREE = 2,                                   // Resource structure needs to be deallocated by xfree()
47 };
48
49 /**
50  * Creates a new resource pool. If a memory pool is given, meta-data of all resources
51  * will be allocated from this pool. Otherwise, they will be malloc'ed.
52  **/
53 struct respool *rp_new(const char *name, struct mempool *mp);
54
55 void rp_delete(struct respool *rp);                     /** Deletes a resource pool, freeing all resources. **/
56 void rp_detach(struct respool *rp);                     /** Deletes a resource pool, detaching all resources. **/
57 void rp_commit(struct respool *rp);                     /** Deletes a resource pool. Temporary resources are freed, stable resources are detached. **/
58 void rp_dump(struct respool *rp, uns indent);           /** Prints out a debugging dump of a pool to stdout. **/
59
60 /** Returns a pointer to the currently active resource pool or NULL, if none exists. **/
61 static inline struct respool *rp_current(void)
62 {
63   return ucwlib_thread_context()->current_respool;
64 }
65
66 /**
67  * Makes the given resource pool active; returns a pointer to the previously active pool
68  * or NULL, if there was none. Calling with @rp equal to NULL deactivates the pool.
69  **/
70 static inline struct respool *rp_switch(struct respool *rp)
71 {
72   struct ucwlib_context *ctx = ucwlib_thread_context();
73   struct respool *orp = ctx->current_respool;
74   ctx->current_respool = rp;
75   return orp;
76 }
77
78 struct resource *res_alloc(const struct res_class *rc) LIKE_MALLOC;     // Dies if there is no pool active
79
80 void res_dump(struct resource *r, uns indent);          /** Prints out a debugging dump of the resource to stdout. **/
81
82 /**
83  * Frees a resource, unlinking it from its pool.
84  * When called with a NULL pointer, it does nothing, but safely.
85  **/
86 void res_free(struct resource *r);
87
88 /**
89  * Unlinks a resource from a pool and releases its meta-data. However, the resource itself is kept.
90  * When called with a NULL pointer, it does nothing, but safely.
91  **/
92 void res_detach(struct resource *r);
93
94 /** Marks a resource as temporary (sets @RES_FLAG_TEMP). **/
95 static inline void res_temporary(struct resource *r)
96 {
97   r->flags |= RES_FLAG_TEMP;
98 }
99
100 /** Marks a resource as permanent (clears @RES_FLAG_TEMP). **/
101 static inline void res_permanent(struct resource *r)
102 {
103   r->flags &= RES_FLAG_TEMP;
104 }
105
106 /***
107  * === Resource classes
108  *
109  * A resource class describes how to handle a particular type of resources.
110  * Most importantly, it defines a set of (optional) callbacks for performing operations
111  * on the resources:
112  *
113  * * dump() should print a description of the resource used for debugging
114  *   to the standard output. The description should end with a newline character
115  *   and in case of a multi-line description, the subsequent lines should be
116  *   indented by @indent spaces.
117  * * free() frees the resource; the struct resource is freed automatically afterwards.
118  * * detach() breaks the link between the struct resource and the real resource;
119  *   the struct resource is freed automatically afterwards, while the resource
120  *   continues to live.
121  *
122  * The following functions are intended for use by the resource classes only.
123  ***/
124
125 /** The structure describing a resource class. **/
126 struct res_class {
127   const char *name;                                     // The name of the class (included in debugging dumps)
128   void (*detach)(struct resource *r);                   // The callbacks
129   void (*free)(struct resource *r);
130   void (*dump)(struct resource *r, uns indent);
131   uns res_size;                                         // Size of the resource structure (0=default)
132 };
133
134 /**
135  * Initialize a pre-allocated buffer to the specific class of resource, setting its private data to @priv.
136  * This resource can be added to the current pool by @res_add().
137  **/
138 static inline struct resource *res_init(struct resource *r, const struct res_class *rc, void *priv)
139 {
140   r->flags = 0;
141   r->rclass = rc;
142   r->priv = priv;
143   return r;
144 }
145
146 /**
147  * Links a pre-initialized resource to the active pool.
148  **/
149 void res_add(struct resource *r);
150
151 /**
152  * Unlinks a resource from a pool and releases its meta-data. Unlike @res_detach(),
153  * it does not invoke any callbacks. The caller must make sure that no references to
154  * the meta-data remain, so this is generally safe only inside resource class code.
155  **/
156 void res_drop(struct resource *r);
157
158 /**
159  * Creates a new resource of the specific class, setting its private data to @priv.
160  * Dies if no resource pool is active.
161  **/
162 static inline struct resource *res_new(const struct res_class *rc, void *priv)
163 {
164   struct resource *r = res_alloc(rc);
165   r->rclass = rc;
166   r->priv = priv;
167   return r;
168 }
169
170 /***
171  * === Pre-defined resource classes
172  ***/
173
174 struct resource *res_for_fd(int fd);                    /** Creates a resource that closes a given file descriptor. **/
175
176 void *res_malloc(size_t size, struct resource **ptr) LIKE_MALLOC;       /** Allocates memory and creates a resource for it. **/
177 void *res_malloc_zero(size_t size, struct resource **ptr) LIKE_MALLOC;  /** Allocates zero-initialized memory and creates a resource for it. **/
178 void *res_realloc(struct resource *res, size_t size);                   /** Re-allocates memory obtained by @res_malloc() or @res_malloc_zero(). **/
179
180 /**
181  * Converts the resource pool @rp to a resource inside the current resource pool (i.e., its sub-pool).
182  * You can delete the sub-pool either by freeing this resource, or by calling
183  * @rp_delete() on it, which removes the resource automatically.
184  **/
185 struct resource *res_subpool(struct respool *rp);
186
187 struct mempool;
188 struct resource *res_mempool(struct mempool *mp);                       /** Creates a resource for the specified <<mempool:,memory pool>>. **/
189
190 struct eltpool;
191 struct resource *res_eltpool(struct eltpool *ep);                       /** Creates a resource for the specified <<eltpool:,element pool>>. **/
192
193 #endif