lib: add internal object pool API and use it; adapt plugins/tests
[babeltrace.git] / include / babeltrace / object-internal.h
index e130a81e883d620cba525cffc28a4ffba2f90fcd..4efba28e8278f8b721c7f06a45794a307dc61ec9 100644 (file)
  * SOFTWARE.
  */
 
+#include <babeltrace/babeltrace-internal.h>
 #include <babeltrace/ref-internal.h>
 #include <babeltrace/ref.h>
+#include <babeltrace/assert-internal.h>
+#include <stdbool.h>
 
 /**
  * All objects publicly exposed by Babeltrace APIs must contain this structure
  */
 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;
+
+       /*
+        * True if this object is shared, that is, it uses reference
+        * counting. Only used in developer mode.
+        */
+       bool is_shared;
 };
 
 static inline
@@ -57,7 +68,12 @@ void bt_object_release(void *ptr)
 {
        struct bt_object *obj = ptr;
 
-       if (obj && obj->release && !bt_object_get_ref_count(obj)) {
+#ifdef BT_LOGV
+       BT_LOGV("Releasing object: addr=%p, ref-count=%lu", ptr,
+               obj->ref_count.count);
+#endif
+
+       if (obj && obj->release && bt_object_get_ref_count(obj) == 0) {
                obj->release(obj);
        }
 }
@@ -66,8 +82,27 @@ static inline
 void generic_release(struct bt_object *obj)
 {
        if (obj->parent) {
+               struct bt_object *parent = obj->parent;
+
+#ifdef BT_LOGV
+               BT_LOGV("Releasing parented object: addr=%p, ref-count=%lu, "
+                       "parent-addr=%p, parent-ref-count=%lu",
+                       obj, obj->ref_count.count,
+                       parent, parent->ref_count.count);
+#endif
+
+               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);
        }
@@ -96,6 +131,11 @@ void bt_object_set_parent(void *child_ptr, void *parent)
                return;
        }
 
+#ifdef BT_LOGV
+       BT_LOGV("Setting object's parent: addr=%p, parent-addr=%p",
+               child_ptr, parent);
+#endif
+
        /*
         * It is assumed that a "child" being "parented" is publicly reachable.
         * Therefore, a reference to its parent must be taken. The reference
@@ -106,6 +146,18 @@ void bt_object_set_parent(void *child_ptr, void *parent)
        child->parent = bt_get(parent);
 }
 
+#ifdef BT_DEV_MODE
+static inline
+void _bt_object_set_is_shared(struct bt_object *obj, bool is_shared)
+{
+       obj->is_shared = is_shared;
+}
+
+# define bt_object_set_is_shared       _bt_object_set_is_shared
+#else
+# define bt_object_set_is_shared(_obj, _is_shared)
+#endif
+
 static inline
 void bt_object_init(void *ptr, bt_object_release_func release)
 {
@@ -113,7 +165,16 @@ void bt_object_init(void *ptr, bt_object_release_func release)
 
        obj->release = release;
        obj->parent = NULL;
+       bt_object_set_is_shared(obj, true);
        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)
+{
+       BT_ASSERT(obj);
+       ((struct bt_object *) obj)->parent_is_owner_listener = cb;
+}
+
 #endif /* BABELTRACE_OBJECT_INTERNAL_H */
This page took 0.026902 seconds and 4 git commands to generate.