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