From: Jérémie Galarneau Date: Mon, 23 Nov 2015 23:14:10 +0000 (-0500) Subject: Add parented object memory management to the Object interface X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=commitdiff_plain;h=5d2d9981bec06082e6148185830b8bcf0a10f4af Add parented object memory management to the Object interface Signed-off-by: Jérémie Galarneau --- diff --git a/include/babeltrace/object-internal.h b/include/babeltrace/object-internal.h index afba4479..0b0fd0f7 100644 --- a/include/babeltrace/object-internal.h +++ b/include/babeltrace/object-internal.h @@ -28,6 +28,7 @@ */ #include +#include /** * All objects publicly exposed by Babeltrace APIs must contain this structure @@ -37,12 +38,71 @@ */ struct bt_object { struct bt_ref ref_count; + /* Class-specific release function. */ + bt_object_release_func release; + /* @see doc/ref-counting.md */ + struct bt_object *parent; }; static inline -void bt_object_init(void *obj, bt_object_release_func release) +long bt_object_get_ref_count(const void *); +static inline +void bt_object_set_parent(void *, void *); + +static +void bt_object_release(void *ptr) +{ + struct bt_object *obj = ptr; + + if (obj && obj->release && !bt_object_get_ref_count(obj)) { + obj->release(obj); + } +} + +static +void generic_release(struct bt_object *obj) +{ + if (obj->parent) { + /* The release function will be invoked by the parent. */ + bt_put(obj->parent); + } else { + bt_object_release(obj); + } +} + +static inline +struct bt_object *bt_object_get_parent(void *ptr) +{ + struct bt_object *obj = ptr; + + return ptr ? bt_get(obj->parent) : NULL; +} + +static inline +void bt_object_set_parent(void *child_ptr, void *parent) { - bt_ref_init(&((struct bt_object *) obj)->ref_count, release); + struct bt_object *child = child_ptr; + + if (!child) { + return; + } + + /* + * It is assumed that a "child" being "parented" is publicly reachable. + * Therefore, a reference to its parent must be taken. The reference + * to the parent will be released once the object's reference count + * falls to zero. + */ + child->parent = bt_get(parent); +} + +static inline +void bt_object_init(void *ptr, bt_object_release_func release) +{ + struct bt_object *obj = ptr; + + obj->release = release; + bt_ref_init(&obj->ref_count, generic_release); } #endif /* BABELTRACE_OBJECT_INTERNAL_H */