X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=include%2Fbabeltrace%2Fobject-internal.h;h=747950f721b76509b4ca6b62cb5956cae920aae9;hb=c40a57e579977be9eb7682480428a89af5ca529c;hp=afba44790723d212465bb9e423278e3ffb647970;hpb=83509119a945fc77faff869daaf48627e1c4b3fa;p=babeltrace.git diff --git a/include/babeltrace/object-internal.h b/include/babeltrace/object-internal.h index afba4479..747950f7 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,80 @@ */ 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) { - bt_ref_init(&((struct bt_object *) obj)->ref_count, release); + struct bt_object *obj = ptr; + + return ptr ? bt_get(obj->parent) : NULL; +} + +static inline +void bt_object_set_parent(void *child_ptr, void *parent) +{ + 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; + obj->parent = NULL; + bt_ref_init(&obj->ref_count, generic_release); +} + +static inline +long bt_object_get_ref_count(const void *ptr) +{ + const struct bt_object *obj = ptr; + + return obj->ref_count.count; } #endif /* BABELTRACE_OBJECT_INTERNAL_H */