Notification iterator: generate automatic notifications when missing
[babeltrace.git] / lib / graph / component.c
index 31abc0737c554574e18e5b09df5bd79ff0474132..8837c0d1fa50dad479c6a36cbbd17db8a6acd3c8 100644 (file)
@@ -70,12 +70,23 @@ void bt_component_destroy(struct bt_object *obj)
 {
        struct bt_component *component = NULL;
        struct bt_component_class *component_class = NULL;
+       int i;
 
        if (!obj) {
                return;
        }
 
        component = container_of(obj, struct bt_component, base);
+
+       /* Call destroy listeners in reverse registration order */
+       for (i = component->destroy_listeners->len - 1; i >= 0; i--) {
+               struct bt_component_destroy_listener *listener =
+                       &g_array_index(component->destroy_listeners,
+                               struct bt_component_destroy_listener, i);
+
+               listener->func(component, listener->data);
+       }
+
        component_class = component->class;
 
        /*
@@ -99,6 +110,10 @@ void bt_component_destroy(struct bt_object *obj)
                g_ptr_array_free(component->output_ports, TRUE);
        }
 
+       if (component->destroy_listeners) {
+               g_array_free(component->destroy_listeners, TRUE);
+       }
+
        g_string_free(component->name, TRUE);
        bt_put(component_class);
        g_free(component);
@@ -250,6 +265,13 @@ struct bt_component *bt_component_create_with_init_method_data(
                goto end;
        }
 
+       component->destroy_listeners = g_array_new(FALSE, TRUE,
+               sizeof(struct bt_component_destroy_listener));
+       if (!component->destroy_listeners) {
+               BT_PUT(component);
+               goto end;
+       }
+
        if (type == BT_COMPONENT_CLASS_TYPE_SOURCE ||
                        type == BT_COMPONENT_CLASS_TYPE_FILTER) {
                default_port = bt_component_add_port(component,
@@ -599,3 +621,37 @@ void bt_component_port_disconnected(struct bt_component *comp,
                        bt_private_port_from_port(port));
        }
 }
+
+BT_HIDDEN
+void bt_component_add_destroy_listener(struct bt_component *component,
+               bt_component_destroy_listener_func func, void *data)
+{
+       struct bt_component_destroy_listener listener;
+
+       assert(component);
+       assert(func);
+       listener.func = func;
+       listener.data = data;
+       g_array_append_val(component->destroy_listeners, listener);
+}
+
+BT_HIDDEN
+void bt_component_remove_destroy_listener(struct bt_component *component,
+               bt_component_destroy_listener_func func, void *data)
+{
+       size_t i;
+
+       assert(component);
+       assert(func);
+
+       for (i = 0; i < component->destroy_listeners->len; i++) {
+               struct bt_component_destroy_listener *listener =
+                       &g_array_index(component->destroy_listeners,
+                               struct bt_component_destroy_listener, i);
+
+               if (listener->func == func && listener->data == data) {
+                       g_array_remove_index(component->destroy_listeners, i);
+                       i--;
+               }
+       }
+}
This page took 0.025118 seconds and 4 git commands to generate.