X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=include%2Fbabeltrace%2Fobject-internal.h;h=545a20aadd21a7f9f9bd3b78971f9e64b0c5182b;hb=f167d3c0c0904ef36e19fcd37f4f20d33b0e76b6;hp=e130a81e883d620cba525cffc28a4ffba2f90fcd;hpb=087bc0603db40d8cd5f4fddf933f3ded4829369e;p=babeltrace.git diff --git a/include/babeltrace/object-internal.h b/include/babeltrace/object-internal.h index e130a81e..545a20aa 100644 --- a/include/babeltrace/object-internal.h +++ b/include/babeltrace/object-internal.h @@ -38,8 +38,10 @@ */ struct bt_object { struct bt_ref ref_count; - /* Class-specific release function. */ + /* Class-specific, optional release function. */ bt_object_release_func release; + /* Class-specific, optional "parent is owner" notification listener. */ + bt_object_release_func parent_is_owner_listener; /* @see doc/ref-counting.md */ struct bt_object *parent; }; @@ -66,8 +68,20 @@ static inline void generic_release(struct bt_object *obj) { if (obj->parent) { + void *parent = obj->parent; + + if (obj->parent_is_owner_listener) { + /* + * Object has a chance to destroy itself here + * under certain conditions and notify its + * parent. At this point the parent is + * guaranteed to exist because it's not put yet. + */ + obj->parent_is_owner_listener(obj); + } + /* The release function will be invoked by the parent. */ - bt_put(obj->parent); + bt_put(parent); } else { bt_object_release(obj); } @@ -116,4 +130,12 @@ void bt_object_init(void *ptr, bt_object_release_func release) bt_ref_init(&obj->ref_count, generic_release); } +static inline +void bt_object_set_parent_is_owner_listener(void *obj, + bt_object_release_func cb) +{ + assert(obj); + ((struct bt_object *) obj)->parent_is_owner_listener = cb; +} + #endif /* BABELTRACE_OBJECT_INTERNAL_H */