Add parented object memory management to the Object interface
authorJérémie Galarneau <jeremie.galarneau@efficios.com>
Mon, 23 Nov 2015 23:14:10 +0000 (18:14 -0500)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Tue, 19 Jan 2016 18:28:18 +0000 (13:28 -0500)
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
include/babeltrace/object-internal.h

index afba44790723d212465bb9e423278e3ffb647970..0b0fd0f7075d523a13a83ae6ffa257c4b774dba4 100644 (file)
@@ -28,6 +28,7 @@
  */
 
 #include <babeltrace/ref-internal.h>
+#include <babeltrace/ref.h>
 
 /**
  * All objects publicly exposed by Babeltrace APIs must contain this structure
  */
 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 */
This page took 0.026042 seconds and 4 git commands to generate.