{
struct respool *rp = rp_current();
ASSERT(rp);
-
uns size = (rc->res_size ? : sizeof(struct resource));
- struct resource *r = (rp->mpool ? mp_alloc_fast(rp->mpool, size) : xmalloc(size));
+ struct resource *r;
+ if (rp->mpool)
+ {
+ r = mp_alloc_fast(rp->mpool, size);
+ r->flags = 0;
+ }
+ else
+ {
+ r = xmalloc(size);
+ r->flags = RES_FLAG_XFREE;
+ }
+ res_add(r);
+ return r;
+}
+
+void
+res_add(struct resource *r)
+{
+ struct respool *rp = rp_current();
+ ASSERT(rp);
r->rpool = rp;
clist_add_tail(&rp->resources, &r->n);
- r->flags = rp->default_res_flags;
- return r;
+ r->flags &= ~RES_FLAG_TEMP;
+ r->flags |= rp->default_res_flags & RES_FLAG_TEMP;
}
void
res_drop(struct resource *r)
{
clist_remove(&r->n);
- if (!r->rpool->mpool)
+ if (r->flags & RES_FLAG_XFREE)
xfree(r);
}
/** Resource flags **/
enum resource_flags {
RES_FLAG_TEMP = 1, // Resource is temporary
+ RES_FLAG_XFREE = 2, // Resource structure needs to be deallocated by xfree()
};
/**
uns res_size; // Size of the resource structure (0=default)
};
+/**
+ * Initialize a pre-allocated buffer to the specific class of resource, setting its private data to @priv.
+ * This resource can be added to the current pool by @res_add().
+ **/
+static inline struct resource *res_init(struct resource *r, const struct res_class *rc, void *priv)
+{
+ r->flags = 0;
+ r->rclass = rc;
+ r->priv = priv;
+ return r;
+}
+
+/**
+ * Links a pre-initialized resource to the active pool.
+ **/
+void res_add(struct resource *r);
+
/**
* Unlinks a resource from a pool and releases its meta-data. Unlike @res_detach(),
* it does not invoke any callbacks. The caller must make sure that no references to