Rename lib/component/ -> lib/graph/ to match include/babeltrace/graph/
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Tue, 4 Apr 2017 18:54:09 +0000 (14:54 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Sun, 28 May 2017 16:57:40 +0000 (12:57 -0400)
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
38 files changed:
configure.ac
lib/Makefile.am
lib/component/Makefile.am [deleted file]
lib/component/clock-class-priority-map.c [deleted file]
lib/component/component-class.c [deleted file]
lib/component/component.c [deleted file]
lib/component/connection.c [deleted file]
lib/component/filter.c [deleted file]
lib/component/graph.c [deleted file]
lib/component/iterator.c [deleted file]
lib/component/notification/Makefile.am [deleted file]
lib/component/notification/event.c [deleted file]
lib/component/notification/heap.c [deleted file]
lib/component/notification/inactivity.c [deleted file]
lib/component/notification/notification.c [deleted file]
lib/component/notification/packet.c [deleted file]
lib/component/notification/stream.c [deleted file]
lib/component/port.c [deleted file]
lib/component/sink.c [deleted file]
lib/component/source.c [deleted file]
lib/graph/Makefile.am [new file with mode: 0644]
lib/graph/clock-class-priority-map.c [new file with mode: 0644]
lib/graph/component-class.c [new file with mode: 0644]
lib/graph/component.c [new file with mode: 0644]
lib/graph/connection.c [new file with mode: 0644]
lib/graph/filter.c [new file with mode: 0644]
lib/graph/graph.c [new file with mode: 0644]
lib/graph/iterator.c [new file with mode: 0644]
lib/graph/notification/Makefile.am [new file with mode: 0644]
lib/graph/notification/event.c [new file with mode: 0644]
lib/graph/notification/heap.c [new file with mode: 0644]
lib/graph/notification/inactivity.c [new file with mode: 0644]
lib/graph/notification/notification.c [new file with mode: 0644]
lib/graph/notification/packet.c [new file with mode: 0644]
lib/graph/notification/stream.c [new file with mode: 0644]
lib/graph/port.c [new file with mode: 0644]
lib/graph/sink.c [new file with mode: 0644]
lib/graph/source.c [new file with mode: 0644]

index c37146597e5319d8482ce17e9b597bfac41312b7..18335bd5649c72ea3e22cc928cf4c1016f462431 100644 (file)
@@ -466,8 +466,8 @@ AC_CONFIG_FILES([
        lib/Makefile
        lib/prio_heap/Makefile
        lib/plugin/Makefile
-        lib/component/Makefile
-       lib/component/notification/Makefile
+       lib/graph/Makefile
+       lib/graph/notification/Makefile
        lib/ctf-ir/Makefile
        lib/ctf-writer/Makefile
        include/Makefile
index 49fff815ce59824f37a584c68c94d0c7c183dd5b..068d858e639ea96565beb6f26e16c87fe5e9000c 100644 (file)
@@ -1,4 +1,4 @@
-SUBDIRS = ctf-ir ctf-writer prio_heap plugin component .
+SUBDIRS = ctf-ir ctf-writer prio_heap plugin graph .
 
 AM_CFLAGS = $(PACKAGE_CFLAGS) -I$(top_srcdir)/include
 
@@ -10,7 +10,7 @@ libbabeltrace_la_LDFLAGS = -version-info $(BABELTRACE_LIBRARY_VERSION)
 libbabeltrace_la_LIBADD = \
        prio_heap/libprio_heap.la \
        $(top_builddir)/compat/libcompat.la \
-       component/libcomponent.la \
+       graph/libgraph.la \
        plugin/libplugin.la \
        $(top_builddir)/common/libbabeltrace-common.la \
        ctf-ir/libctf-ir.la \
diff --git a/lib/component/Makefile.am b/lib/component/Makefile.am
deleted file mode 100644 (file)
index a72766e..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-AM_CFLAGS = $(PACKAGE_CFLAGS) -I$(top_srcdir)/include
-
-SUBDIRS = notification
-
-noinst_LTLIBRARIES = libcomponent.la
-
-# Plug-in system library
-libcomponent_la_SOURCES = \
-       clock-class-priority-map.c \
-       component.c \
-       component-class.c \
-       graph.c \
-       connection.c \
-       port.c \
-       source.c \
-       sink.c \
-       filter.c \
-       iterator.c
-
-libcomponent_la_LIBADD = \
-       notification/libcomponent-notification.la
diff --git a/lib/component/clock-class-priority-map.c b/lib/component/clock-class-priority-map.c
deleted file mode 100644 (file)
index f905519..0000000
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * clock-class-priority-map.c
- *
- * Copyright 2017 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/graph/clock-class-priority-map.h>
-#include <babeltrace/graph/clock-class-priority-map-internal.h>
-#include <babeltrace/ctf-ir/clock-class.h>
-#include <babeltrace/ctf-ir/clock-class-internal.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/compiler-internal.h>
-#include <babeltrace/ref.h>
-#include <glib.h>
-
-static
-void bt_clock_class_priority_map_destroy(struct bt_object *obj)
-{
-       struct bt_clock_class_priority_map *cc_prio_map = (void *) obj;
-
-       if (!cc_prio_map) {
-               return;
-       }
-
-       if (cc_prio_map->entries) {
-               g_ptr_array_free(cc_prio_map->entries, TRUE);
-       }
-
-       if (cc_prio_map->prios) {
-               g_hash_table_destroy(cc_prio_map->prios);
-       }
-
-       g_free(cc_prio_map);
-}
-
-struct bt_clock_class_priority_map *bt_clock_class_priority_map_create()
-{
-       struct bt_clock_class_priority_map *cc_prio_map = NULL;
-
-       cc_prio_map = g_new0(struct bt_clock_class_priority_map, 1);
-       if (!cc_prio_map) {
-               goto error;
-       }
-
-       bt_object_init(cc_prio_map, bt_clock_class_priority_map_destroy);
-       cc_prio_map->entries = g_ptr_array_new_with_free_func(
-               (GDestroyNotify) bt_put);
-       if (!cc_prio_map->entries) {
-               goto error;
-       }
-
-       cc_prio_map->prios = g_hash_table_new_full(g_direct_hash,
-               g_direct_equal, NULL, (GDestroyNotify) g_free);
-       if (!cc_prio_map->entries) {
-               goto error;
-       }
-
-       goto end;
-
-error:
-       BT_PUT(cc_prio_map);
-
-end:
-       return cc_prio_map;
-}
-
-int bt_clock_class_priority_map_get_clock_class_count(
-               struct bt_clock_class_priority_map *cc_prio_map)
-{
-       int ret = -1;
-
-       if (!cc_prio_map) {
-               goto end;
-       }
-
-       ret = (int) cc_prio_map->entries->len;
-
-end:
-       return ret;
-}
-
-struct bt_ctf_clock_class *bt_clock_class_priority_map_get_clock_class(
-               struct bt_clock_class_priority_map *cc_prio_map,
-               unsigned int index)
-{
-       struct bt_ctf_clock_class *clock_class = NULL;
-
-       if (!cc_prio_map || index >= cc_prio_map->entries->len) {
-               goto end;
-       }
-
-       clock_class = g_ptr_array_index(cc_prio_map->entries, index);
-       bt_get(clock_class);
-
-end:
-       return clock_class;
-}
-
-struct bt_ctf_clock_class *bt_clock_class_priority_map_get_clock_class_by_name(
-               struct bt_clock_class_priority_map *cc_prio_map,
-               const char *name)
-{
-       size_t i;
-       struct bt_ctf_clock_class *clock_class = NULL;
-
-       if (!cc_prio_map || !name) {
-               goto end;
-       }
-
-       for (i = 0; i < cc_prio_map->entries->len; i++) {
-               struct bt_ctf_clock_class *cur_cc =
-                       g_ptr_array_index(cc_prio_map->entries, i);
-               // FIXME when available: use bt_ctf_clock_class_get_name()
-               const char *cur_cc_name =
-                       cur_cc->name ? cur_cc->name->str : NULL;
-
-               if (!cur_cc_name) {
-                       goto end;
-               }
-
-               if (strcmp(cur_cc_name, name) == 0) {
-                       clock_class = bt_get(cur_cc);
-                       goto end;
-               }
-       }
-
-end:
-       return clock_class;
-}
-
-
-struct clock_class_prio {
-       uint64_t prio;
-       struct bt_ctf_clock_class *clock_class;
-};
-
-static
-void current_highest_prio_gh_func(gpointer key, gpointer value,
-               gpointer user_data)
-{
-       struct clock_class_prio *func_data = user_data;
-       uint64_t *prio = value;
-
-       if (*prio <= func_data->prio) {
-               func_data->prio = *prio;
-               func_data->clock_class = key;
-       }
-}
-
-static
-struct clock_class_prio bt_ctf_clock_class_priority_map_current_highest_prio(
-               struct bt_clock_class_priority_map *cc_prio_map)
-{
-       struct clock_class_prio func_data = {
-               .prio = -1ULL,
-               .clock_class = NULL,
-       };
-
-       g_hash_table_foreach(cc_prio_map->prios, current_highest_prio_gh_func,
-               &func_data);
-       return func_data;
-}
-
-struct bt_ctf_clock_class *
-bt_clock_class_priority_map_get_highest_priority_clock_class(
-               struct bt_clock_class_priority_map *cc_prio_map)
-{
-       struct bt_ctf_clock_class *clock_class = NULL;
-
-       if (!cc_prio_map) {
-               goto end;
-       }
-
-       clock_class = bt_get(cc_prio_map->highest_prio_cc);
-
-end:
-       return clock_class;
-}
-
-int bt_clock_class_priority_map_get_clock_class_priority(
-               struct bt_clock_class_priority_map *cc_prio_map,
-               struct bt_ctf_clock_class *clock_class, uint64_t *priority)
-{
-       int ret = 0;
-       uint64_t *prio;
-
-       if (!cc_prio_map || !clock_class || !priority) {
-               ret = -1;
-               goto end;
-       }
-
-       prio = g_hash_table_lookup(cc_prio_map->prios, clock_class);
-       if (!prio) {
-               ret = -1;
-               goto end;
-       }
-
-       *priority = *prio;
-
-end:
-       return ret;
-}
-
-int bt_clock_class_priority_map_add_clock_class(
-               struct bt_clock_class_priority_map *cc_prio_map,
-               struct bt_ctf_clock_class *clock_class, uint64_t priority)
-{
-       int ret = 0;
-       uint64_t *prio_ptr = NULL;
-       struct clock_class_prio cc_prio;
-
-       // FIXME when available: check
-       // bt_ctf_clock_class_is_valid(clock_class)
-       if (!cc_prio_map) {
-               ret = -1;
-               goto end;
-       }
-
-       /* Check for duplicate clock classes */
-       prio_ptr = g_hash_table_lookup(cc_prio_map->prios, clock_class);
-       if (prio_ptr) {
-               prio_ptr = NULL;
-               ret = -1;
-               goto end;
-       }
-
-       prio_ptr = g_new(uint64_t, 1);
-       if (!prio_ptr) {
-               ret = -1;
-               goto end;
-       }
-
-       *prio_ptr = priority;
-       bt_get(clock_class);
-       g_ptr_array_add(cc_prio_map->entries, clock_class);
-       g_hash_table_insert(cc_prio_map->prios, clock_class, prio_ptr);
-       prio_ptr = NULL;
-       cc_prio = bt_ctf_clock_class_priority_map_current_highest_prio(
-               cc_prio_map);
-       assert(cc_prio.clock_class);
-       cc_prio_map->highest_prio_cc = cc_prio.clock_class;
-
-end:
-       if (prio_ptr) {
-               g_free(prio_ptr);
-       }
-
-       return ret;
-}
diff --git a/lib/component/component-class.c b/lib/component/component-class.c
deleted file mode 100644 (file)
index 4585b1f..0000000
+++ /dev/null
@@ -1,544 +0,0 @@
-/*
- * component-class.c
- *
- * Babeltrace Plugin Component Class
- *
- * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/compiler-internal.h>
-#include <babeltrace/graph/component-class-internal.h>
-#include <babeltrace/ref.h>
-#include <stdbool.h>
-#include <glib.h>
-
-static
-void bt_component_class_destroy(struct bt_object *obj)
-{
-       struct bt_component_class *class;
-       int i;
-
-       assert(obj);
-       class = container_of(obj, struct bt_component_class, base);
-
-       /* Call destroy listeners in reverse registration order */
-       for (i = class->destroy_listeners->len - 1; i >= 0; i--) {
-               struct bt_component_class_destroy_listener *listener =
-                       &g_array_index(class->destroy_listeners,
-                               struct bt_component_class_destroy_listener,
-                               i);
-
-               listener->func(class, listener->data);
-       }
-
-       if (class->name) {
-               g_string_free(class->name, TRUE);
-       }
-       if (class->description) {
-               g_string_free(class->description, TRUE);
-       }
-       if (class->help) {
-               g_string_free(class->help, TRUE);
-       }
-       if (class->destroy_listeners) {
-               g_array_free(class->destroy_listeners, TRUE);
-       }
-
-       g_free(class);
-}
-
-static
-int bt_component_class_init(struct bt_component_class *class,
-               enum bt_component_class_type type, const char *name)
-{
-       int ret = 0;
-
-       bt_object_init(class, bt_component_class_destroy);
-       class->type = type;
-       class->name = g_string_new(name);
-       if (!class->name) {
-               goto error;
-       }
-
-       class->description = g_string_new(NULL);
-       if (!class->description) {
-               goto error;
-       }
-
-       class->help = g_string_new(NULL);
-       if (!class->help) {
-               goto error;
-       }
-
-       class->destroy_listeners = g_array_new(FALSE, TRUE,
-               sizeof(struct bt_component_class_destroy_listener));
-       if (!class->destroy_listeners) {
-               goto error;
-       }
-
-       goto end;
-
-error:
-       BT_PUT(class);
-       ret = -1;
-
-end:
-       return ret;
-}
-
-struct bt_component_class *bt_component_class_source_create(const char *name,
-               bt_component_class_notification_iterator_next_method notification_iterator_next_method)
-{
-       struct bt_component_class_source *source_class = NULL;
-       int ret;
-
-       if (!name || !notification_iterator_next_method) {
-               goto end;
-       }
-
-       source_class = g_new0(struct bt_component_class_source, 1);
-       if (!source_class) {
-               goto end;
-       }
-
-       ret = bt_component_class_init(&source_class->parent,
-               BT_COMPONENT_CLASS_TYPE_SOURCE, name);
-       if (ret) {
-               /*
-                * If bt_component_class_init() fails, the component
-                * class is put, therefore its memory is already
-                * freed.
-                */
-               source_class = NULL;
-               goto end;
-       }
-
-       source_class->methods.iterator.next = notification_iterator_next_method;
-
-end:
-       return &source_class->parent;
-}
-
-struct bt_component_class *bt_component_class_filter_create(const char *name,
-               bt_component_class_notification_iterator_next_method notification_iterator_next_method)
-{
-       struct bt_component_class_filter *filter_class = NULL;
-       int ret;
-
-       if (!name || !notification_iterator_next_method) {
-               goto end;
-       }
-
-       filter_class = g_new0(struct bt_component_class_filter, 1);
-       if (!filter_class) {
-               goto end;
-       }
-
-       ret = bt_component_class_init(&filter_class->parent,
-               BT_COMPONENT_CLASS_TYPE_FILTER, name);
-       if (ret) {
-               /*
-                * If bt_component_class_init() fails, the component
-                * class is put, therefore its memory is already
-                * freed.
-                */
-               filter_class = NULL;
-               goto end;
-       }
-
-       filter_class->methods.iterator.next = notification_iterator_next_method;
-
-end:
-       return &filter_class->parent;
-}
-
-struct bt_component_class *bt_component_class_sink_create(const char *name,
-               bt_component_class_sink_consume_method consume_method)
-{
-       struct bt_component_class_sink *sink_class = NULL;
-       int ret;
-
-       if (!name || !consume_method) {
-               goto end;
-       }
-
-       sink_class = g_new0(struct bt_component_class_sink, 1);
-       if (!sink_class) {
-               goto end;
-       }
-
-       ret = bt_component_class_init(&sink_class->parent,
-               BT_COMPONENT_CLASS_TYPE_SINK, name);
-       if (ret) {
-               /*
-                * If bt_component_class_init() fails, the component
-                * class is put, therefore its memory is already
-                * freed.
-                */
-               sink_class = NULL;
-               goto end;
-       }
-
-       sink_class->methods.consume = consume_method;
-
-end:
-       return &sink_class->parent;
-}
-
-int bt_component_class_set_init_method(
-               struct bt_component_class *component_class,
-               bt_component_class_init_method init_method)
-{
-       int ret = 0;
-
-       if (!component_class || component_class->frozen || !init_method) {
-               ret = -1;
-               goto end;
-       }
-
-       component_class->methods.init = init_method;
-
-end:
-       return ret;
-}
-
-int bt_component_class_set_query_method(
-               struct bt_component_class *component_class,
-               bt_component_class_query_method query_method)
-{
-       int ret = 0;
-
-       if (!component_class || component_class->frozen || !query_method) {
-               ret = -1;
-               goto end;
-       }
-
-       component_class->methods.query = query_method;
-
-end:
-       return ret;
-}
-
-int bt_component_class_set_accept_port_connection_method(
-               struct bt_component_class *component_class,
-               bt_component_class_accept_port_connection_method method)
-{
-       int ret = 0;
-
-       if (!component_class || component_class->frozen || !method) {
-               ret = -1;
-               goto end;
-       }
-
-       component_class->methods.accept_port_connection = method;
-
-end:
-       return ret;
-}
-
-int bt_component_class_set_port_disconnected_method(
-               struct bt_component_class *component_class,
-               bt_component_class_port_disconnected_method method)
-{
-       int ret = 0;
-
-       if (!component_class || component_class->frozen || !method) {
-               ret = -1;
-               goto end;
-       }
-
-       component_class->methods.port_disconnected = method;
-
-end:
-       return ret;
-}
-
-int bt_component_class_set_finalize_method(
-               struct bt_component_class *component_class,
-               bt_component_class_finalize_method finalize_method)
-{
-       int ret = 0;
-
-       if (!component_class || component_class->frozen || !finalize_method) {
-               ret = -1;
-               goto end;
-       }
-
-       component_class->methods.finalize = finalize_method;
-
-end:
-       return ret;
-}
-
-int bt_component_class_source_set_notification_iterator_init_method(
-               struct bt_component_class *component_class,
-               bt_component_class_notification_iterator_init_method notification_iterator_init_method)
-{
-       struct bt_component_class_source *source_class;
-       int ret = 0;
-
-       if (!component_class || component_class->frozen ||
-                       !notification_iterator_init_method ||
-                       component_class->type != BT_COMPONENT_CLASS_TYPE_SOURCE) {
-               ret = -1;
-               goto end;
-       }
-
-       source_class = container_of(component_class,
-               struct bt_component_class_source, parent);
-       source_class->methods.iterator.init = notification_iterator_init_method;
-
-end:
-       return ret;
-}
-
-int bt_component_class_source_set_notification_iterator_finalize_method(
-               struct bt_component_class *component_class,
-               bt_component_class_notification_iterator_finalize_method notification_iterator_finalize_method)
-{
-       struct bt_component_class_source *source_class;
-       int ret = 0;
-
-       if (!component_class || component_class->frozen ||
-                       !notification_iterator_finalize_method ||
-                       component_class->type != BT_COMPONENT_CLASS_TYPE_SOURCE) {
-               ret = -1;
-               goto end;
-       }
-
-       source_class = container_of(component_class,
-               struct bt_component_class_source, parent);
-       source_class->methods.iterator.finalize =
-               notification_iterator_finalize_method;
-
-end:
-       return ret;
-}
-
-int bt_component_class_source_set_notification_iterator_seek_time_method(
-               struct bt_component_class *component_class,
-               bt_component_class_notification_iterator_seek_time_method notification_iterator_seek_time_method)
-{
-       struct bt_component_class_source *source_class;
-       int ret = 0;
-
-       if (!component_class || component_class->frozen ||
-                       !notification_iterator_seek_time_method ||
-                       component_class->type != BT_COMPONENT_CLASS_TYPE_SOURCE) {
-               ret = -1;
-               goto end;
-       }
-
-       source_class = container_of(component_class,
-               struct bt_component_class_source, parent);
-       source_class->methods.iterator.seek_time =
-               notification_iterator_seek_time_method;
-
-end:
-       return ret;
-}
-
-int bt_component_class_filter_set_notification_iterator_init_method(
-               struct bt_component_class *component_class,
-               bt_component_class_notification_iterator_init_method notification_iterator_init_method)
-{
-       struct bt_component_class_filter *filter_class;
-       int ret = 0;
-
-       if (!component_class || component_class->frozen ||
-                       !notification_iterator_init_method ||
-                       component_class->type != BT_COMPONENT_CLASS_TYPE_FILTER) {
-               ret = -1;
-               goto end;
-       }
-
-       filter_class = container_of(component_class,
-               struct bt_component_class_filter, parent);
-       filter_class->methods.iterator.init = notification_iterator_init_method;
-
-end:
-       return ret;
-}
-
-int bt_component_class_filter_set_notification_iterator_finalize_method(
-               struct bt_component_class *component_class,
-               bt_component_class_notification_iterator_finalize_method notification_iterator_finalize_method)
-{
-       struct bt_component_class_filter *filter_class;
-       int ret = 0;
-
-       if (!component_class || component_class->frozen ||
-                       !notification_iterator_finalize_method ||
-                       component_class->type != BT_COMPONENT_CLASS_TYPE_FILTER) {
-               ret = -1;
-               goto end;
-       }
-
-       filter_class = container_of(component_class,
-               struct bt_component_class_filter, parent);
-       filter_class->methods.iterator.finalize =
-               notification_iterator_finalize_method;
-
-end:
-       return ret;
-}
-
-int bt_component_class_filter_set_notification_iterator_seek_time_method(
-               struct bt_component_class *component_class,
-               bt_component_class_notification_iterator_seek_time_method notification_iterator_seek_time_method)
-{
-       struct bt_component_class_filter *filter_class;
-       int ret = 0;
-
-       if (!component_class || component_class->frozen ||
-                       !notification_iterator_seek_time_method ||
-                       component_class->type != BT_COMPONENT_CLASS_TYPE_FILTER) {
-               ret = -1;
-               goto end;
-       }
-
-       filter_class = container_of(component_class,
-               struct bt_component_class_filter, parent);
-       filter_class->methods.iterator.seek_time =
-               notification_iterator_seek_time_method;
-
-end:
-       return ret;
-}
-
-int bt_component_class_set_description(
-               struct bt_component_class *component_class,
-               const char *description)
-{
-       int ret = 0;
-
-       if (!component_class || component_class->frozen || !description) {
-               ret = -1;
-               goto end;
-       }
-
-       g_string_assign(component_class->description, description);
-
-end:
-       return ret;
-}
-
-int bt_component_class_set_help(
-               struct bt_component_class *component_class,
-               const char *help)
-{
-       int ret = 0;
-
-       if (!component_class || component_class->frozen || !help) {
-               ret = -1;
-               goto end;
-       }
-
-       g_string_assign(component_class->help, help);
-
-end:
-       return ret;
-}
-
-const char *bt_component_class_get_name(
-               struct bt_component_class *component_class)
-{
-       return component_class ? component_class->name->str : NULL;
-}
-
-enum bt_component_class_type bt_component_class_get_type(
-               struct bt_component_class *component_class)
-{
-       return component_class ? component_class->type :
-                       BT_COMPONENT_CLASS_TYPE_UNKNOWN;
-}
-
-const char *bt_component_class_get_description(
-               struct bt_component_class *component_class)
-{
-       return component_class && component_class->description &&
-               component_class->description->str[0] != '\0' ?
-               component_class->description->str : NULL;
-}
-
-const char *bt_component_class_get_help(
-               struct bt_component_class *component_class)
-{
-       return component_class && component_class->help &&
-               component_class->help->str[0] != '\0' ?
-               component_class->help->str : NULL;
-}
-
-BT_HIDDEN
-int bt_component_class_add_destroy_listener(struct bt_component_class *class,
-               bt_component_class_destroy_listener_func func, void *data)
-{
-       int ret = 0;
-       struct bt_component_class_destroy_listener listener;
-
-       if (!class || class->frozen || !func) {
-               ret = -1;
-               goto end;
-       }
-
-       listener.func = func;
-       listener.data = data;
-       g_array_append_val(class->destroy_listeners, listener);
-
-end:
-       return ret;
-}
-
-int bt_component_class_freeze(
-               struct bt_component_class *component_class)
-{
-       int ret = 0;
-
-       if (!component_class) {
-               ret = -1;
-               goto end;
-       }
-
-       component_class->frozen = true;
-
-end:
-       return ret;
-}
-
-struct bt_value *bt_component_class_query(
-               struct bt_component_class *component_class,
-               const char *object, struct bt_value *params)
-{
-       struct bt_value *results = NULL;
-
-       if (!component_class || !object || !params ||
-                       !component_class->methods.query) {
-               goto end;
-       }
-
-       results = component_class->methods.query(component_class,
-               object, params);
-
-end:
-       return results;
-}
diff --git a/lib/component/component.c b/lib/component/component.c
deleted file mode 100644 (file)
index 9b996f6..0000000
+++ /dev/null
@@ -1,568 +0,0 @@
-/*
- * component.c
- *
- * Babeltrace Plugin Component
- *
- * Copyright 2015 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/graph/private-component.h>
-#include <babeltrace/graph/component.h>
-#include <babeltrace/graph/component-internal.h>
-#include <babeltrace/graph/component-class-internal.h>
-#include <babeltrace/graph/component-source-internal.h>
-#include <babeltrace/graph/component-filter-internal.h>
-#include <babeltrace/graph/component-sink-internal.h>
-#include <babeltrace/graph/private-connection.h>
-#include <babeltrace/graph/connection-internal.h>
-#include <babeltrace/graph/graph-internal.h>
-#include <babeltrace/graph/notification-iterator-internal.h>
-#include <babeltrace/graph/private-notification-iterator.h>
-#include <babeltrace/babeltrace-internal.h>
-#include <babeltrace/compiler-internal.h>
-#include <babeltrace/ref.h>
-
-static
-struct bt_component * (* const component_create_funcs[])(
-               struct bt_component_class *, struct bt_value *) = {
-       [BT_COMPONENT_CLASS_TYPE_SOURCE] = bt_component_source_create,
-       [BT_COMPONENT_CLASS_TYPE_SINK] = bt_component_sink_create,
-       [BT_COMPONENT_CLASS_TYPE_FILTER] = bt_component_filter_create,
-};
-
-static
-void (*component_destroy_funcs[])(struct bt_component *) = {
-       [BT_COMPONENT_CLASS_TYPE_SOURCE] = bt_component_source_destroy,
-       [BT_COMPONENT_CLASS_TYPE_SINK] = bt_component_sink_destroy,
-       [BT_COMPONENT_CLASS_TYPE_FILTER] = bt_component_filter_destroy,
-};
-
-static
-enum bt_component_status (* const component_validation_funcs[])(
-               struct bt_component *) = {
-       [BT_COMPONENT_CLASS_TYPE_SOURCE] = bt_component_source_validate,
-       [BT_COMPONENT_CLASS_TYPE_SINK] = bt_component_sink_validate,
-       [BT_COMPONENT_CLASS_TYPE_FILTER] = bt_component_filter_validate,
-};
-
-static
-void bt_component_destroy(struct bt_object *obj)
-{
-       struct bt_component *component = NULL;
-       struct bt_component_class *component_class = NULL;
-
-       if (!obj) {
-               return;
-       }
-
-       component = container_of(obj, struct bt_component, base);
-       component_class = component->class;
-
-       /*
-        * User data is destroyed first, followed by the concrete component
-        * instance.
-        */
-       if (component->class->methods.finalize) {
-               component->class->methods.finalize(
-                       bt_private_component_from_component(component));
-       }
-
-       if (component->destroy) {
-               component->destroy(component);
-       }
-
-       if (component->input_ports) {
-               g_ptr_array_free(component->input_ports, TRUE);
-       }
-
-       if (component->output_ports) {
-               g_ptr_array_free(component->output_ports, TRUE);
-       }
-
-       g_string_free(component->name, TRUE);
-       bt_put(component_class);
-       g_free(component);
-}
-
-struct bt_component *bt_component_from_private_component(
-               struct bt_private_component *private_component)
-{
-       return bt_get(bt_component_from_private(private_component));
-}
-
-enum bt_component_class_type bt_component_get_class_type(
-               struct bt_component *component)
-{
-       return component ? component->class->type : BT_COMPONENT_CLASS_TYPE_UNKNOWN;
-}
-
-static
-struct bt_port *bt_component_add_port(
-               struct bt_component *component, GPtrArray *ports,
-               enum bt_port_type port_type, const char *name)
-{
-       size_t i;
-       struct bt_port *new_port = NULL;
-       struct bt_graph *graph = NULL;
-
-       if (!name || strlen(name) == 0) {
-               goto end;
-       }
-
-       /* Look for a port having the same name. */
-       for (i = 0; i < ports->len; i++) {
-               const char *port_name;
-               struct bt_port *port = g_ptr_array_index(
-                               ports, i);
-
-               port_name = bt_port_get_name(port);
-               if (!port_name) {
-                       continue;
-               }
-
-               if (!strcmp(name, port_name)) {
-                       /* Port name clash, abort. */
-                       goto end;
-               }
-       }
-
-       new_port = bt_port_create(component, port_type, name);
-       if (!new_port) {
-               goto end;
-       }
-
-       /*
-        * No name clash, add the port.
-        * The component is now the port's parent; it should _not_
-        * hold a reference to the port since the port's lifetime
-        * is now protected by the component's own lifetime.
-        */
-       g_ptr_array_add(ports, new_port);
-
-       /*
-        * Notify the graph's creator that a new port was added.
-        */
-       graph = bt_component_get_graph(component);
-       if (graph) {
-               bt_graph_notify_port_added(graph, new_port);
-               BT_PUT(graph);
-       }
-
-end:
-       return new_port;
-}
-
-BT_HIDDEN
-uint64_t bt_component_get_input_port_count(struct bt_component *comp)
-{
-       assert(comp);
-       return comp->input_ports->len;
-}
-
-BT_HIDDEN
-uint64_t bt_component_get_output_port_count(struct bt_component *comp)
-{
-       assert(comp);
-       return comp->output_ports->len;
-}
-
-struct bt_component *bt_component_create_with_init_method_data(
-               struct bt_component_class *component_class, const char *name,
-               struct bt_value *params, void *init_method_data)
-{
-       int ret;
-       struct bt_component *component = NULL;
-       enum bt_component_class_type type;
-       struct bt_port *default_port = NULL;
-
-       if (!component_class) {
-               goto end;
-       }
-
-       type = bt_component_class_get_type(component_class);
-       if (type <= BT_COMPONENT_CLASS_TYPE_UNKNOWN ||
-                       type > BT_COMPONENT_CLASS_TYPE_FILTER) {
-               goto end;
-       }
-
-       component = component_create_funcs[type](component_class, params);
-       if (!component) {
-               goto end;
-       }
-
-       bt_object_init(component, bt_component_destroy);
-       component->class = bt_get(component_class);
-       component->destroy = component_destroy_funcs[type];
-       component->name = g_string_new(name);
-       if (!component->name) {
-               BT_PUT(component);
-               goto end;
-       }
-
-       component->input_ports = g_ptr_array_new_with_free_func(
-               bt_object_release);
-       if (!component->input_ports) {
-               BT_PUT(component);
-               goto end;
-       }
-
-       component->output_ports = g_ptr_array_new_with_free_func(
-               bt_object_release);
-       if (!component->output_ports) {
-               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,
-                       component->output_ports, BT_PORT_TYPE_OUTPUT,
-                       DEFAULT_OUTPUT_PORT_NAME);
-               if (!default_port) {
-                       BT_PUT(component);
-                       goto end;
-               }
-
-               BT_PUT(default_port);
-       }
-
-       if (type == BT_COMPONENT_CLASS_TYPE_FILTER ||
-                       type == BT_COMPONENT_CLASS_TYPE_SINK) {
-               default_port = bt_component_add_port(component,
-                       component->input_ports, BT_PORT_TYPE_INPUT,
-                       DEFAULT_INPUT_PORT_NAME);
-               if (!default_port) {
-                       BT_PUT(component);
-                       goto end;
-               }
-
-               BT_PUT(default_port);
-       }
-
-       component->initializing = true;
-
-       if (component_class->methods.init) {
-               ret = component_class->methods.init(
-                       bt_private_component_from_component(component), params,
-                       init_method_data);
-               component->initializing = false;
-               if (ret != BT_COMPONENT_STATUS_OK) {
-                       BT_PUT(component);
-                       goto end;
-               }
-       }
-
-       component->initializing = false;
-       ret = component_validation_funcs[type](component);
-       if (ret != BT_COMPONENT_STATUS_OK) {
-               BT_PUT(component);
-               goto end;
-       }
-
-       bt_component_class_freeze(component->class);
-end:
-       bt_put(default_port);
-       return component;
-}
-
-struct bt_component *bt_component_create(
-               struct bt_component_class *component_class, const char *name,
-               struct bt_value *params)
-{
-       return bt_component_create_with_init_method_data(component_class, name,
-               params, NULL);
-}
-
-const char *bt_component_get_name(struct bt_component *component)
-{
-       const char *ret = NULL;
-
-       if (!component) {
-               goto end;
-       }
-
-       ret = component->name->len == 0 ? NULL : component->name->str;
-end:
-       return ret;
-}
-
-enum bt_component_status bt_component_set_name(struct bt_component *component,
-               const char *name)
-{
-       enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
-
-       if (!component || !name || name[0] == '\0') {
-               ret = BT_COMPONENT_STATUS_INVALID;
-               goto end;
-       }
-
-       g_string_assign(component->name, name);
-end:
-       return ret;
-}
-
-struct bt_component_class *bt_component_get_class(
-               struct bt_component *component)
-{
-       return component ? bt_get(component->class) : NULL;
-}
-
-void *bt_private_component_get_user_data(
-               struct bt_private_component *private_component)
-{
-       struct bt_component *component =
-               bt_component_from_private(private_component);
-
-       return component ? component->user_data : NULL;
-}
-
-enum bt_component_status bt_private_component_set_user_data(
-               struct bt_private_component *private_component,
-               void *data)
-{
-       struct bt_component *component =
-               bt_component_from_private(private_component);
-       enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
-
-       if (!component || !component->initializing) {
-               ret = BT_COMPONENT_STATUS_INVALID;
-               goto end;
-       }
-
-       component->user_data = data;
-end:
-       return ret;
-}
-
-BT_HIDDEN
-void bt_component_set_graph(struct bt_component *component,
-               struct bt_graph *graph)
-{
-       struct bt_object *parent = bt_object_get_parent(&component->base);
-
-       assert(!parent || parent == &graph->base);
-       if (!parent) {
-               bt_object_set_parent(component, &graph->base);
-       }
-       bt_put(parent);
-}
-
-struct bt_graph *bt_component_get_graph(
-               struct bt_component *component)
-{
-       return (struct bt_graph *) bt_object_get_parent(&component->base);
-}
-
-static
-struct bt_port *bt_component_get_port(GPtrArray *ports, const char *name)
-{
-       size_t i;
-       struct bt_port *ret_port = NULL;
-
-       assert(name);
-
-       for (i = 0; i < ports->len; i++) {
-               struct bt_port *port = g_ptr_array_index(ports, i);
-               const char *port_name = bt_port_get_name(port);
-
-               if (!port_name) {
-                       continue;
-               }
-
-               if (!strcmp(name, port_name)) {
-                       ret_port = bt_get(port);
-                       break;
-               }
-       }
-
-       return ret_port;
-}
-
-BT_HIDDEN
-struct bt_port *bt_component_get_input_port(struct bt_component *comp,
-               const char *name)
-{
-       assert(comp);
-
-       return bt_component_get_port(comp->input_ports, name);
-}
-
-BT_HIDDEN
-struct bt_port *bt_component_get_output_port(struct bt_component *comp,
-               const char *name)
-{
-       assert(comp);
-
-       return bt_component_get_port(comp->output_ports, name);
-}
-
-static
-struct bt_port *bt_component_get_port_at_index(GPtrArray *ports, int index)
-{
-       struct bt_port *port = NULL;
-
-       if (index < 0 || index >= ports->len) {
-               goto end;
-       }
-
-       port = bt_get(g_ptr_array_index(ports, index));
-end:
-       return port;
-}
-
-BT_HIDDEN
-struct bt_port *bt_component_get_input_port_at_index(struct bt_component *comp,
-               int index)
-{
-       assert(comp);
-
-       return bt_component_get_port_at_index(comp->input_ports, index);
-}
-
-BT_HIDDEN
-struct bt_port *bt_component_get_output_port_at_index(struct bt_component *comp,
-               int index)
-{
-       assert(comp);
-
-       return bt_component_get_port_at_index(comp->output_ports, index);
-}
-
-BT_HIDDEN
-struct bt_port *bt_component_add_input_port(
-               struct bt_component *component, const char *name)
-{
-       return bt_component_add_port(component, component->input_ports,
-               BT_PORT_TYPE_INPUT, name);
-}
-
-BT_HIDDEN
-struct bt_port *bt_component_add_output_port(
-               struct bt_component *component, const char *name)
-{
-       return bt_component_add_port(component, component->output_ports,
-               BT_PORT_TYPE_OUTPUT, name);
-}
-
-static
-void bt_component_remove_port_at_index(struct bt_component *component,
-               GPtrArray *ports, size_t index)
-{
-       struct bt_port *port;
-       struct bt_graph *graph;
-
-       assert(ports);
-       assert(index < ports->len);
-       port = g_ptr_array_index(ports, index);
-
-       /* Disconnect both ports of this port's connection, if any */
-       if (port->connection) {
-               bt_connection_disconnect_ports(port->connection);
-       }
-
-       /* Remove from parent's array of ports (weak refs) */
-       g_ptr_array_remove_index(ports, index);
-
-       /* Detach port from its component parent */
-       BT_PUT(port->base.parent);
-
-       /*
-        * Notify the graph's creator that a port is removed.
-        */
-       graph = bt_component_get_graph(component);
-       if (graph) {
-               bt_graph_notify_port_removed(graph, component, port);
-               BT_PUT(graph);
-       }
-}
-
-BT_HIDDEN
-enum bt_component_status bt_component_remove_port(
-               struct bt_component *component, struct bt_port *port)
-{
-       size_t i;
-       enum bt_component_status status = BT_COMPONENT_STATUS_OK;
-       GPtrArray *ports = NULL;
-
-       if (!component || !port) {
-               status = BT_COMPONENT_STATUS_INVALID;
-               goto end;
-       }
-
-       if (bt_port_get_type(port) == BT_PORT_TYPE_INPUT) {
-               ports = component->input_ports;
-       } else if (bt_port_get_type(port) == BT_PORT_TYPE_OUTPUT) {
-               ports = component->output_ports;
-       }
-
-       assert(ports);
-
-       for (i = 0; i < ports->len; i++) {
-               struct bt_port *cur_port = g_ptr_array_index(ports, i);
-
-               if (cur_port == port) {
-                       bt_component_remove_port_at_index(component,
-                               ports, i);
-                       goto end;
-               }
-       }
-
-       status = BT_COMPONENT_STATUS_NOT_FOUND;
-end:
-       return status;
-}
-
-BT_HIDDEN
-enum bt_component_status bt_component_accept_port_connection(
-               struct bt_component *comp, struct bt_port *self_port,
-               struct bt_port *other_port)
-{
-       enum bt_component_status status = BT_COMPONENT_STATUS_OK;
-
-       assert(comp);
-       assert(self_port);
-       assert(other_port);
-
-       if (comp->class->methods.accept_port_connection) {
-               status = comp->class->methods.accept_port_connection(
-                       bt_private_component_from_component(comp),
-                       bt_private_port_from_port(self_port),
-                       other_port);
-       }
-
-       return status;
-}
-
-BT_HIDDEN
-void bt_component_port_disconnected(struct bt_component *comp,
-               struct bt_port *port)
-{
-       assert(comp);
-       assert(port);
-
-       if (comp->class->methods.port_disconnected) {
-               comp->class->methods.port_disconnected(
-                       bt_private_component_from_component(comp),
-                       bt_private_port_from_port(port));
-       }
-}
diff --git a/lib/component/connection.c b/lib/component/connection.c
deleted file mode 100644 (file)
index 986303e..0000000
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * connection.c
- *
- * Babeltrace Connection
- *
- * Copyright 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/graph/notification-iterator-internal.h>
-#include <babeltrace/graph/component-internal.h>
-#include <babeltrace/graph/component-source-internal.h>
-#include <babeltrace/graph/component-filter-internal.h>
-#include <babeltrace/graph/connection-internal.h>
-#include <babeltrace/graph/private-connection.h>
-#include <babeltrace/graph/graph-internal.h>
-#include <babeltrace/graph/port-internal.h>
-#include <babeltrace/object-internal.h>
-#include <babeltrace/compiler-internal.h>
-#include <glib.h>
-
-static
-void bt_connection_destroy(struct bt_object *obj)
-{
-       struct bt_connection *connection = container_of(obj,
-                       struct bt_connection, base);
-
-       /*
-        * No bt_put on ports as a connection only holds _weak_ references
-        * to them.
-        */
-       g_free(connection);
-}
-
-struct bt_connection *bt_connection_from_private_connection(
-               struct bt_private_connection *private_connection)
-{
-       return bt_get(bt_connection_from_private(private_connection));
-}
-
-BT_HIDDEN
-struct bt_connection *bt_connection_create(
-               struct bt_graph *graph,
-               struct bt_port *upstream_port,
-               struct bt_port *downstream_port)
-{
-       struct bt_connection *connection = NULL;
-
-       if (bt_port_get_type(upstream_port) != BT_PORT_TYPE_OUTPUT) {
-               goto end;
-       }
-       if (bt_port_get_type(downstream_port) != BT_PORT_TYPE_INPUT) {
-               goto end;
-       }
-
-       connection = g_new0(struct bt_connection, 1);
-       if (!connection) {
-               goto end;
-       }
-
-       bt_object_init(connection, bt_connection_destroy);
-       /* Weak references are taken, see comment in header. */
-       connection->upstream_port = upstream_port;
-       connection->downstream_port = downstream_port;
-       bt_port_set_connection(upstream_port, connection);
-       bt_port_set_connection(downstream_port, connection);
-       bt_object_set_parent(connection, &graph->base);
-end:
-       return connection;
-}
-
-BT_HIDDEN
-void bt_connection_disconnect_ports(struct bt_connection *conn)
-{
-       struct bt_component *downstream_comp = NULL;
-       struct bt_component *upstream_comp = NULL;
-       struct bt_port *downstream_port = conn->downstream_port;
-       struct bt_port *upstream_port = conn->upstream_port;
-       struct bt_graph *graph = (void *) bt_object_get_parent(conn);
-
-       if (downstream_port) {
-               downstream_comp = bt_port_get_component(downstream_port);
-               bt_port_set_connection(downstream_port, NULL);
-               conn->downstream_port = NULL;
-       }
-
-       if (upstream_port) {
-               upstream_comp = bt_port_get_component(upstream_port);
-               bt_port_set_connection(upstream_port, NULL);
-               conn->upstream_port = NULL;
-       }
-
-       if (downstream_comp) {
-               bt_component_port_disconnected(downstream_comp,
-                       downstream_port);
-       }
-
-       if (upstream_comp) {
-               bt_component_port_disconnected(upstream_comp, upstream_port);
-       }
-
-       assert(graph);
-       bt_graph_notify_ports_disconnected(graph, upstream_comp,
-               downstream_comp, upstream_port, downstream_port);
-       bt_put(downstream_comp);
-       bt_put(upstream_comp);
-       bt_put(graph);
-}
-
-struct bt_port *bt_connection_get_upstream_port(
-               struct bt_connection *connection)
-{
-       return connection ? bt_get(connection->upstream_port) : NULL;
-}
-
-struct bt_port *bt_connection_get_downstream_port(
-               struct bt_connection *connection)
-{
-       return connection ? bt_get(connection->downstream_port) : NULL;
-}
-
-struct bt_notification_iterator *
-bt_private_connection_create_notification_iterator(
-               struct bt_private_connection *private_connection)
-{
-       enum bt_notification_iterator_status ret_iterator;
-       enum bt_component_class_type upstream_comp_class_type;
-       struct bt_notification_iterator *iterator = NULL;
-       struct bt_port *upstream_port = NULL;
-       struct bt_component *upstream_component = NULL;
-       struct bt_component_class *upstream_comp_class = NULL;
-       struct bt_connection *connection = NULL;
-       bt_component_class_notification_iterator_init_method init_method = NULL;
-
-       if (!private_connection) {
-               goto error;
-       }
-
-       connection = bt_connection_from_private(private_connection);
-
-       if (!connection->upstream_port || !connection->downstream_port) {
-               goto error;
-       }
-
-       upstream_port = connection->upstream_port;
-       assert(upstream_port);
-       upstream_component = bt_port_get_component(upstream_port);
-       assert(upstream_component);
-       upstream_comp_class = upstream_component->class;
-
-       if (!upstream_component) {
-               goto error;
-       }
-
-       upstream_comp_class_type =
-               bt_component_get_class_type(upstream_component);
-       if (upstream_comp_class_type != BT_COMPONENT_CLASS_TYPE_SOURCE &&
-                       upstream_comp_class_type != BT_COMPONENT_CLASS_TYPE_FILTER) {
-               /* Unsupported operation. */
-               goto error;
-       }
-
-       iterator = bt_notification_iterator_create(upstream_component);
-       if (!iterator) {
-               goto error;
-       }
-
-       switch (upstream_comp_class_type) {
-       case BT_COMPONENT_CLASS_TYPE_SOURCE:
-       {
-               struct bt_component_class_source *source_class =
-                       container_of(upstream_comp_class,
-                               struct bt_component_class_source, parent);
-               init_method = source_class->methods.iterator.init;
-               break;
-       }
-       case BT_COMPONENT_CLASS_TYPE_FILTER:
-       {
-               struct bt_component_class_filter *filter_class =
-                       container_of(upstream_comp_class,
-                               struct bt_component_class_filter, parent);
-               init_method = filter_class->methods.iterator.init;
-               break;
-       }
-       default:
-               /* Unreachable. */
-               assert(0);
-       }
-
-       if (init_method) {
-               enum bt_notification_iterator_status status = init_method(
-                       bt_private_notification_iterator_from_notification_iterator(iterator),
-                       bt_private_port_from_port(upstream_port));
-               if (status < 0) {
-                       goto error;
-               }
-       }
-
-       ret_iterator = bt_notification_iterator_validate(iterator);
-       if (ret_iterator != BT_NOTIFICATION_ITERATOR_STATUS_OK) {
-               goto error;
-       }
-
-       goto end;
-
-error:
-       BT_PUT(iterator);
-
-end:
-       bt_put(upstream_component);
-       return iterator;
-}
diff --git a/lib/component/filter.c b/lib/component/filter.c
deleted file mode 100644 (file)
index 5931b3b..0000000
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * filter.c
- *
- * Babeltrace Filter Component
- *
- * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/compiler-internal.h>
-#include <babeltrace/values.h>
-#include <babeltrace/graph/component-filter-internal.h>
-#include <babeltrace/graph/component-internal.h>
-#include <babeltrace/graph/component-class-internal.h>
-#include <babeltrace/graph/notification.h>
-#include <babeltrace/graph/notification-iterator-internal.h>
-
-BT_HIDDEN
-void bt_component_filter_destroy(struct bt_component *component)
-{
-}
-
-BT_HIDDEN
-struct bt_component *bt_component_filter_create(
-               struct bt_component_class *class, struct bt_value *params)
-{
-       struct bt_component_filter *filter = NULL;
-
-       filter = g_new0(struct bt_component_filter, 1);
-       if (!filter) {
-               goto end;
-       }
-
-end:
-       return filter ? &filter->parent : NULL;
-}
-
-BT_HIDDEN
-enum bt_component_status bt_component_filter_validate(
-               struct bt_component *component)
-{
-       enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
-
-       if (!component) {
-               ret = BT_COMPONENT_STATUS_INVALID;
-               goto end;
-       }
-
-       if (!component->class) {
-               ret = BT_COMPONENT_STATUS_INVALID;
-               goto end;
-       }
-
-       if (component->class->type != BT_COMPONENT_CLASS_TYPE_FILTER) {
-               ret = BT_COMPONENT_STATUS_INVALID;
-               goto end;
-       }
-
-       /* Enforce iterator limits. */
-end:
-       return ret;
-}
-
-enum bt_component_status bt_component_filter_get_input_port_count(
-               struct bt_component *component, uint64_t *count)
-{
-       enum bt_component_status status = BT_COMPONENT_STATUS_OK;
-
-       if (!component || !count ||
-                       component->class->type != BT_COMPONENT_CLASS_TYPE_FILTER) {
-               status = BT_COMPONENT_STATUS_INVALID;
-               goto end;
-       }
-
-       *count = bt_component_get_input_port_count(component);
-end:
-       return status;
-}
-
-struct bt_port *bt_component_filter_get_input_port(
-               struct bt_component *component, const char *name)
-{
-       struct bt_port *port = NULL;
-
-       if (!component || !name ||
-                       component->class->type != BT_COMPONENT_CLASS_TYPE_FILTER) {
-               goto end;
-       }
-
-       port = bt_component_get_input_port(component, name);
-end:
-       return port;
-}
-
-struct bt_port *bt_component_filter_get_input_port_at_index(
-               struct bt_component *component, int index)
-{
-       struct bt_port *port = NULL;
-
-       if (!component ||
-                       component->class->type != BT_COMPONENT_CLASS_TYPE_FILTER) {
-               goto end;
-       }
-
-       port = bt_component_get_input_port_at_index(component, index);
-end:
-       return port;
-}
-
-struct bt_port *bt_component_filter_get_default_input_port(
-               struct bt_component *component)
-{
-       return bt_component_filter_get_input_port(component,
-                       DEFAULT_INPUT_PORT_NAME);
-}
-
-enum bt_component_status bt_component_filter_get_output_port_count(
-               struct bt_component *component, uint64_t *count)
-{
-       enum bt_component_status status = BT_COMPONENT_STATUS_OK;
-
-       if (!component || !count ||
-                       component->class->type != BT_COMPONENT_CLASS_TYPE_FILTER) {
-               status = BT_COMPONENT_STATUS_INVALID;
-               goto end;
-       }
-
-       *count = bt_component_get_output_port_count(component);
-end:
-       return status;
-}
-
-struct bt_port *bt_component_filter_get_output_port(
-               struct bt_component *component, const char *name)
-{
-       struct bt_port *port = NULL;
-
-       if (!component || !name ||
-                       component->class->type != BT_COMPONENT_CLASS_TYPE_FILTER) {
-               goto end;
-       }
-
-       port = bt_component_get_output_port(component, name);
-end:
-       return port;
-}
-
-struct bt_port *bt_component_filter_get_output_port_at_index(
-               struct bt_component *component, int index)
-{
-       struct bt_port *port = NULL;
-
-       if (!component ||
-                       component->class->type != BT_COMPONENT_CLASS_TYPE_FILTER) {
-               goto end;
-       }
-
-       port = bt_component_get_output_port_at_index(component, index);
-end:
-       return port;
-}
-
-struct bt_port *bt_component_filter_get_default_output_port(
-               struct bt_component *component)
-{
-       return bt_component_filter_get_output_port(component,
-                       DEFAULT_OUTPUT_PORT_NAME);
-}
-
-struct bt_private_port *
-bt_private_component_filter_get_input_private_port_at_index(
-               struct bt_private_component *private_component, int index)
-{
-       return bt_private_port_from_port(
-               bt_component_filter_get_input_port_at_index(
-                       bt_component_from_private(private_component), index));
-}
-
-struct bt_private_port *
-bt_private_component_filter_get_default_input_private_port(
-               struct bt_private_component *private_component)
-{
-       return bt_private_port_from_port(
-               bt_component_filter_get_default_input_port(
-                       bt_component_from_private(private_component)));
-}
-
-struct bt_private_port *bt_private_component_filter_add_input_private_port(
-               struct bt_private_component *private_component,
-               const char *name)
-{
-       struct bt_port *port = NULL;
-       struct bt_component *component =
-               bt_component_from_private(private_component);
-
-       if (!component ||
-                       component->class->type != BT_COMPONENT_CLASS_TYPE_FILTER) {
-               goto end;
-       }
-
-       port = bt_component_add_input_port(component, name);
-end:
-       return bt_private_port_from_port(port);
-}
-
-struct bt_private_port *
-bt_private_component_filter_get_output_private_port_at_index(
-               struct bt_private_component *private_component, int index)
-{
-       return bt_private_port_from_port(
-               bt_component_filter_get_output_port_at_index(
-                       bt_component_from_private(private_component), index));
-}
-
-struct bt_private_port *
-bt_private_component_filter_get_default_output_private_port(
-               struct bt_private_component *private_component)
-{
-       return bt_private_port_from_port(
-               bt_component_filter_get_default_output_port(
-                       bt_component_from_private(private_component)));
-}
-
-struct bt_private_port *bt_private_component_filter_add_output_private_port(
-               struct bt_private_component *private_component,
-               const char *name)
-{
-       struct bt_port *port = NULL;
-       struct bt_component *component =
-               bt_component_from_private(private_component);
-
-       if (!component ||
-                       component->class->type != BT_COMPONENT_CLASS_TYPE_FILTER) {
-               goto end;
-       }
-
-       port = bt_component_add_output_port(component, name);
-end:
-       return bt_private_port_from_port(port);
-}
diff --git a/lib/component/graph.c b/lib/component/graph.c
deleted file mode 100644 (file)
index c861fa3..0000000
+++ /dev/null
@@ -1,777 +0,0 @@
-/*
- * graph.c
- *
- * Babeltrace Plugin Component Graph
- *
- * Copyright 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/graph/component-internal.h>
-#include <babeltrace/graph/graph-internal.h>
-#include <babeltrace/graph/connection-internal.h>
-#include <babeltrace/graph/component-sink-internal.h>
-#include <babeltrace/graph/component-source.h>
-#include <babeltrace/graph/component-filter.h>
-#include <babeltrace/graph/port.h>
-#include <babeltrace/compiler-internal.h>
-#include <unistd.h>
-#include <glib.h>
-
-struct bt_graph_listener {
-       void *func;
-       void *data;
-};
-
-static
-void bt_graph_destroy(struct bt_object *obj)
-{
-       struct bt_graph *graph = container_of(obj,
-                       struct bt_graph, base);
-
-       if (graph->components) {
-               g_ptr_array_free(graph->components, TRUE);
-       }
-       if (graph->connections) {
-               g_ptr_array_free(graph->connections, TRUE);
-       }
-       if (graph->sinks_to_consume) {
-               g_queue_free(graph->sinks_to_consume);
-       }
-
-       if (graph->listeners.port_added) {
-               g_array_free(graph->listeners.port_added, TRUE);
-       }
-
-       if (graph->listeners.port_removed) {
-               g_array_free(graph->listeners.port_removed, TRUE);
-       }
-
-       if (graph->listeners.ports_connected) {
-               g_array_free(graph->listeners.ports_connected, TRUE);
-       }
-
-       if (graph->listeners.ports_disconnected) {
-               g_array_free(graph->listeners.ports_disconnected, TRUE);
-       }
-
-       g_free(graph);
-}
-
-static
-int init_listeners_array(GArray **listeners)
-{
-       int ret = 0;
-
-       assert(listeners);
-       *listeners = g_array_new(FALSE, TRUE, sizeof(struct bt_graph_listener));
-       if (!*listeners) {
-               ret = -1;
-               goto end;
-       }
-
-end:
-       return ret;
-}
-
-struct bt_graph *bt_graph_create(void)
-{
-       struct bt_graph *graph;
-       int ret;
-
-       graph = g_new0(struct bt_graph, 1);
-       if (!graph) {
-               goto end;
-       }
-
-       bt_object_init(graph, bt_graph_destroy);
-
-       graph->connections = g_ptr_array_new_with_free_func(bt_object_release);
-       if (!graph->connections) {
-               goto error;
-       }
-       graph->components = g_ptr_array_new_with_free_func(bt_object_release);
-       if (!graph->components) {
-               goto error;
-       }
-       graph->sinks_to_consume = g_queue_new();
-       if (!graph->sinks_to_consume) {
-               goto error;
-       }
-
-       ret = init_listeners_array(&graph->listeners.port_added);
-       if (ret) {
-               goto error;
-       }
-
-       ret = init_listeners_array(&graph->listeners.port_removed);
-       if (ret) {
-               goto error;
-       }
-
-       ret = init_listeners_array(&graph->listeners.ports_connected);
-       if (ret) {
-               goto error;
-       }
-
-       ret = init_listeners_array(&graph->listeners.ports_disconnected);
-       if (ret) {
-               goto error;
-       }
-
-end:
-       return graph;
-error:
-       BT_PUT(graph);
-       goto end;
-}
-
-struct bt_connection *bt_graph_connect_ports(struct bt_graph *graph,
-               struct bt_port *upstream_port,
-               struct bt_port *downstream_port)
-{
-       struct bt_connection *connection = NULL;
-       struct bt_graph *upstream_graph = NULL;
-       struct bt_graph *downstream_graph = NULL;
-       struct bt_component *upstream_component = NULL;
-       struct bt_component *downstream_component = NULL;
-       struct bt_connection *existing_conn = NULL;
-       enum bt_component_status component_status;
-       bool upstream_was_already_in_graph;
-       bool downstream_was_already_in_graph;
-       int components_to_remove = 0;
-       int i;
-
-       if (!graph || !upstream_port || !downstream_port) {
-               goto end;
-       }
-
-       /* Ensure appropriate types for upstream and downstream ports. */
-       if (bt_port_get_type(upstream_port) != BT_PORT_TYPE_OUTPUT) {
-               goto end;
-       }
-       if (bt_port_get_type(downstream_port) != BT_PORT_TYPE_INPUT) {
-               goto end;
-       }
-
-       /* Ensure that both ports are currently unconnected. */
-       existing_conn = bt_port_get_connection(upstream_port);
-       bt_put(existing_conn);
-       if (existing_conn) {
-               fprintf(stderr, "Upstream port is already connected\n");
-               goto end;
-       }
-
-       existing_conn = bt_port_get_connection(downstream_port);
-       bt_put(existing_conn);
-       if (existing_conn) {
-               fprintf(stderr, "Downstream port is already connected\n");
-               goto end;
-       }
-
-       /*
-        * Ensure that both ports are still attached to their creating
-        * component.
-        */
-       upstream_component = bt_port_get_component(upstream_port);
-       if (!upstream_component) {
-               fprintf(stderr, "Upstream port does not belong to a component\n");
-               goto end;
-       }
-
-       downstream_component = bt_port_get_component(downstream_port);
-       if (!downstream_component) {
-               fprintf(stderr, "Downstream port does not belong to a component\n");
-               goto end;
-       }
-
-       /* Ensure the components are not already part of another graph. */
-       upstream_graph = bt_component_get_graph(upstream_component);
-       if (upstream_graph && (graph != upstream_graph)) {
-               fprintf(stderr, "Upstream component is already part of another graph\n");
-               goto error;
-       }
-       upstream_was_already_in_graph = (graph == upstream_graph);
-       downstream_graph = bt_component_get_graph(downstream_component);
-       if (downstream_graph && (graph != downstream_graph)) {
-               fprintf(stderr, "Downstream component is already part of another graph\n");
-               goto error;
-       }
-       downstream_was_already_in_graph = (graph == downstream_graph);
-
-       connection = bt_connection_create(graph, upstream_port,
-                       downstream_port);
-       if (!connection) {
-               goto error;
-       }
-
-       /*
-        * Ownership of upstream_component/downstream_component and of
-        * the connection object is transferred to the graph.
-        */
-       g_ptr_array_add(graph->connections, connection);
-
-       if (!upstream_was_already_in_graph) {
-               g_ptr_array_add(graph->components, upstream_component);
-               bt_component_set_graph(upstream_component, graph);
-       }
-       if (!downstream_was_already_in_graph) {
-               g_ptr_array_add(graph->components, downstream_component);
-               bt_component_set_graph(downstream_component, graph);
-               if (bt_component_get_class_type(downstream_component) ==
-                               BT_COMPONENT_CLASS_TYPE_SINK) {
-                       g_queue_push_tail(graph->sinks_to_consume,
-                                       downstream_component);
-               }
-       }
-
-       /*
-        * The graph is now the parent of these components which garantees their
-        * existence for the duration of the graph's lifetime.
-        */
-
-       /*
-        * The components and connection are added to the graph before
-        * invoking the `accept_port_connection` method in order to make
-        * them visible to the components during the method's
-        * invocation.
-        */
-       component_status = bt_component_accept_port_connection(
-               upstream_component, upstream_port, downstream_port);
-       if (component_status != BT_COMPONENT_STATUS_OK) {
-               goto error_rollback;
-       }
-       component_status = bt_component_accept_port_connection(
-               downstream_component, downstream_port, upstream_port);
-       if (component_status != BT_COMPONENT_STATUS_OK) {
-               goto error_rollback;
-       }
-
-       /*
-        * Both components accepted the connection. Notify the graph's
-        * creator that both ports are connected.
-        */
-       bt_graph_notify_ports_connected(graph, upstream_port, downstream_port);
-
-end:
-       bt_put(upstream_graph);
-       bt_put(downstream_graph);
-       bt_put(upstream_component);
-       bt_put(downstream_component);
-       return connection;
-error_rollback:
-       /*
-        * Remove newly-added components from the graph, being careful
-        * not to remove a component that was already present in the graph
-        * and is connected to other components.
-        */
-       components_to_remove += upstream_was_already_in_graph ? 0 : 1;
-       components_to_remove += downstream_was_already_in_graph ? 0 : 1;
-
-       if (!downstream_was_already_in_graph) {
-               if (bt_component_get_class_type(downstream_component) ==
-                               BT_COMPONENT_CLASS_TYPE_SINK) {
-                       g_queue_pop_tail(graph->sinks_to_consume);
-               }
-       }
-       /* Remove newly created connection. */
-       g_ptr_array_set_size(graph->connections,
-                       graph->connections->len - 1);
-
-       /*
-        * Remove newly added components.
-        *
-        * Note that this is a tricky situation. The graph, being the parent
-        * of the components, does not hold a reference to them. Normally,
-        * components are destroyed right away when the graph is released since
-        * the graph, being their parent, bounds their lifetime
-        * (see doc/ref-counting.md).
-        *
-        * In this particular case, we must take a number of steps:
-        *   1) unset the components' parent to rollback the initial state of
-        *      the components being connected.
-        *      Note that the reference taken by the component on its graph is
-        *      released by the set_parent call.
-        *   2) set the pointer in the components array to NULL so that the
-        *      destruction function called on the array's resize in invoked on
-        *      NULL (no effect),
-        *
-        * NOTE: Point #1 assumes that *something* holds a reference to both
-        *       components being connected. The fact that a reference is being
-        *       held to a component means that it must hold a reference to its
-        *       parent to prevent the parent from being destroyed (again, refer
-        *       to doc/red-counting.md). This reference to a component is
-        *       most likely being held *transitively* by the caller which holds
-        *       a reference to both ports (a port has its component as a
-        *       parent).
-        *
-        *       This assumes that a graph is not connecting components by
-        *       itself while not holding a reference to the ports/components
-        *       being connected (i.e. "cheating" by using internal APIs).
-        */
-       for (i = 0; i < components_to_remove; i++) {
-               struct bt_component *component = g_ptr_array_index(
-                               graph->components, graph->components->len - 1);
-
-               bt_component_set_graph(component, NULL);
-               g_ptr_array_index(graph->components,
-                               graph->components->len - 1) = NULL;
-               g_ptr_array_set_size(graph->components,
-                               graph->components->len - 1);
-       }
-       /* NOTE: Resizing the ptr_arrays invokes the destruction of the elements. */
-       goto end;
-error:
-       BT_PUT(upstream_component);
-       BT_PUT(downstream_component);
-       goto end;
-}
-
-static
-enum bt_component_status get_component_port_counts(
-               struct bt_component *component, uint64_t *input_count,
-               uint64_t *output_count)
-{
-       enum bt_component_status ret;
-
-       switch (bt_component_get_class_type(component)) {
-       case BT_COMPONENT_CLASS_TYPE_SOURCE:
-               ret = bt_component_source_get_output_port_count(component,
-                               output_count);
-               if (ret != BT_COMPONENT_STATUS_OK) {
-                       goto end;
-               }
-               break;
-       case BT_COMPONENT_CLASS_TYPE_FILTER:
-               ret = bt_component_filter_get_output_port_count(component,
-                               output_count);
-               if (ret != BT_COMPONENT_STATUS_OK) {
-                       goto end;
-               }
-               ret = bt_component_filter_get_input_port_count(component,
-                               input_count);
-               if (ret != BT_COMPONENT_STATUS_OK) {
-                       goto end;
-               }
-               break;
-       case BT_COMPONENT_CLASS_TYPE_SINK:
-               ret = bt_component_sink_get_input_port_count(component,
-                               input_count);
-               if (ret != BT_COMPONENT_STATUS_OK) {
-                       goto end;
-               }
-               break;
-       default:
-               assert(false);
-               break;
-       }
-       ret = BT_COMPONENT_STATUS_OK;
-end:
-       return ret;
-}
-
-enum bt_graph_status bt_graph_add_component_as_sibling(struct bt_graph *graph,
-               struct bt_component *origin,
-               struct bt_component *new_component)
-{
-       uint64_t origin_input_port_count = 0;
-       uint64_t origin_output_port_count = 0;
-       uint64_t new_input_port_count = 0;
-       uint64_t new_output_port_count = 0;
-       enum bt_graph_status status = BT_GRAPH_STATUS_OK;
-       struct bt_graph *origin_graph = NULL;
-       struct bt_graph *new_graph = NULL;
-       struct bt_port *origin_port = NULL;
-       struct bt_port *new_port = NULL;
-       struct bt_port *upstream_port = NULL;
-       struct bt_port *downstream_port = NULL;
-       struct bt_connection *origin_connection = NULL;
-       struct bt_connection *new_connection = NULL;
-        int port_index;
-
-       if (!graph || !origin || !new_component) {
-               status = BT_GRAPH_STATUS_INVALID;
-               goto end;
-       }
-
-       if (bt_component_get_class_type(origin) !=
-                       bt_component_get_class_type(new_component)) {
-               status = BT_GRAPH_STATUS_INVALID;
-               goto end;
-       }
-
-        origin_graph = bt_component_get_graph(origin);
-       if (!origin_graph || (origin_graph != graph)) {
-               status = BT_GRAPH_STATUS_INVALID;
-               goto end;
-       }
-
-        new_graph = bt_component_get_graph(new_component);
-       if (new_graph) {
-               status = BT_GRAPH_STATUS_ALREADY_IN_A_GRAPH;
-               goto end;
-       }
-
-       if (get_component_port_counts(origin, &origin_input_port_count,
-                       &origin_output_port_count) != BT_COMPONENT_STATUS_OK) {
-               status = BT_GRAPH_STATUS_INVALID;
-               goto end;
-       }
-       if (get_component_port_counts(new_component, &new_input_port_count,
-                       &new_output_port_count) != BT_COMPONENT_STATUS_OK) {
-               status = BT_GRAPH_STATUS_INVALID;
-               goto end;
-       }
-
-       if (origin_input_port_count != new_input_port_count ||
-                       origin_output_port_count != new_output_port_count) {
-               status = BT_GRAPH_STATUS_INVALID;
-               goto end;
-       }
-
-       /* Replicate input connections. */
-       for (port_index = 0; port_index< origin_input_port_count; port_index++) {
-               origin_port = bt_component_get_input_port_at_index(origin,
-                       port_index);
-               if (!origin_port) {
-                       status = BT_GRAPH_STATUS_ERROR;
-                       goto error_disconnect;
-               }
-
-               new_port = bt_component_get_input_port_at_index(new_component,
-                       port_index);
-               if (!new_port) {
-                       status = BT_GRAPH_STATUS_ERROR;
-                       goto error_disconnect;
-               }
-
-               origin_connection = bt_port_get_connection(origin_port);
-               if (origin_connection) {
-                       upstream_port = bt_connection_get_upstream_port(
-                               origin_connection);
-                       if (!upstream_port) {
-                               goto error_disconnect;
-                       }
-
-                       new_connection = bt_graph_connect_ports(graph,
-                               upstream_port, new_port);
-                       if (!new_connection) {
-                               goto error_disconnect;
-                       }
-               }
-
-               BT_PUT(upstream_port);
-               BT_PUT(origin_connection);
-               BT_PUT(new_connection);
-               BT_PUT(origin_port);
-               BT_PUT(new_port);
-       }
-
-       /* Replicate output connections. */
-       for (port_index = 0; port_index < origin_output_port_count; port_index++) {
-               origin_port = bt_component_get_output_port_at_index(origin,
-                       port_index);
-               if (!origin_port) {
-                       status = BT_GRAPH_STATUS_ERROR;
-                       goto error_disconnect;
-               }
-               new_port = bt_component_get_output_port_at_index(new_component,
-                       port_index);
-               if (!new_port) {
-                       status = BT_GRAPH_STATUS_ERROR;
-                       goto error_disconnect;
-               }
-
-               origin_connection = bt_port_get_connection(origin_port);
-               if (origin_connection) {
-                       downstream_port = bt_connection_get_downstream_port(
-                                       origin_connection);
-                       if (!downstream_port) {
-                               goto error_disconnect;
-                       }
-
-                       new_connection = bt_graph_connect_ports(graph,
-                               new_port, downstream_port);
-                       if (!new_connection) {
-                               goto error_disconnect;
-                       }
-               }
-
-               BT_PUT(downstream_port);
-               BT_PUT(origin_connection);
-               BT_PUT(new_connection);
-               BT_PUT(origin_port);
-               BT_PUT(new_port);
-       }
-end:
-       bt_put(origin_graph);
-       bt_put(new_graph);
-       bt_put(origin_port);
-       bt_put(new_port);
-       bt_put(upstream_port);
-       bt_put(downstream_port);
-       bt_put(origin_connection);
-       bt_put(new_connection);
-       return status;
-error_disconnect:
-       /* Destroy all connections of the new component. */
-       /* FIXME. */
-       goto end;
-}
-
-enum bt_graph_status bt_graph_consume(struct bt_graph *graph)
-{
-       struct bt_component *sink;
-       enum bt_graph_status status = BT_GRAPH_STATUS_OK;
-       enum bt_component_status comp_status;
-       GList *current_node;
-
-       if (!graph) {
-               status = BT_GRAPH_STATUS_INVALID;
-               goto end;
-       }
-
-       if (g_queue_is_empty(graph->sinks_to_consume)) {
-               status = BT_GRAPH_STATUS_END;
-               goto end;
-       }
-
-       current_node = g_queue_pop_head_link(graph->sinks_to_consume);
-       sink = current_node->data;
-       comp_status = bt_component_sink_consume(sink);
-       switch (comp_status) {
-       case BT_COMPONENT_STATUS_OK:
-               break;
-       case BT_COMPONENT_STATUS_END:
-               status = BT_GRAPH_STATUS_END;
-               break;
-       case BT_COMPONENT_STATUS_AGAIN:
-               status = BT_GRAPH_STATUS_AGAIN;
-               break;
-       case BT_COMPONENT_STATUS_INVALID:
-               status = BT_GRAPH_STATUS_INVALID;
-               break;
-       default:
-               status = BT_GRAPH_STATUS_ERROR;
-               break;
-       }
-
-       if (status != BT_GRAPH_STATUS_END) {
-               g_queue_push_tail_link(graph->sinks_to_consume, current_node);
-               goto end;
-       }
-
-       /* End reached, the node is not added back to the queue and free'd. */
-       g_queue_delete_link(graph->sinks_to_consume, current_node);
-
-       /* Don't forward an END status if there are sinks left to consume. */
-       if (!g_queue_is_empty(graph->sinks_to_consume)) {
-               status = BT_GRAPH_STATUS_OK;
-               goto end;
-       }
-end:
-       return status;
-}
-
-enum bt_graph_status bt_graph_run(struct bt_graph *graph)
-{
-       enum bt_graph_status status = BT_GRAPH_STATUS_OK;
-
-       if (!graph) {
-               status = BT_GRAPH_STATUS_INVALID;
-               goto error;
-       }
-
-       do {
-               status = bt_graph_consume(graph);
-               if (status == BT_GRAPH_STATUS_AGAIN) {
-                       /*
-                        * If AGAIN is received and there are multiple sinks,
-                        * go ahead and consume from the next sink.
-                        *
-                        * However, in the case where a single sink is left,
-                        * the caller can decide to busy-wait and call
-                        * bt_graph_run continuously until the source is ready
-                        * or it can decide to sleep for an arbitrary amount of
-                        * time.
-                        */
-                       if (graph->sinks_to_consume->length > 1) {
-                               status = BT_GRAPH_STATUS_OK;
-                       }
-               }
-       } while (status == BT_GRAPH_STATUS_OK);
-
-       if (g_queue_is_empty(graph->sinks_to_consume)) {
-               status = BT_GRAPH_STATUS_END;
-       }
-error:
-       return status;
-}
-
-static
-void add_listener(GArray *listeners, void *func, void *data)
-{
-       struct bt_graph_listener listener = {
-               .func = func,
-               .data = data,
-       };
-
-       g_array_append_val(listeners, listener);
-}
-
-enum bt_graph_status bt_graph_add_port_added_listener(
-               struct bt_graph *graph,
-               bt_graph_port_added_listener listener, void *data)
-{
-       enum bt_graph_status status = BT_GRAPH_STATUS_OK;
-
-       if (!graph || !listener) {
-               status = BT_GRAPH_STATUS_INVALID;
-               goto end;
-       }
-
-       add_listener(graph->listeners.port_added, listener, data);
-
-end:
-       return status;
-}
-
-enum bt_graph_status bt_graph_add_port_removed_listener(
-               struct bt_graph *graph,
-               bt_graph_port_removed_listener listener, void *data)
-{
-       enum bt_graph_status status = BT_GRAPH_STATUS_OK;
-
-       if (!graph || !listener) {
-               status = BT_GRAPH_STATUS_INVALID;
-               goto end;
-       }
-
-       add_listener(graph->listeners.port_removed, listener, data);
-
-end:
-       return status;
-}
-
-enum bt_graph_status bt_graph_add_ports_connected_listener(
-               struct bt_graph *graph,
-               bt_graph_ports_connected_listener listener, void *data)
-{
-       enum bt_graph_status status = BT_GRAPH_STATUS_OK;
-
-       if (!graph || !listener) {
-               status = BT_GRAPH_STATUS_INVALID;
-               goto end;
-       }
-
-       add_listener(graph->listeners.ports_connected, listener, data);
-
-end:
-       return status;
-}
-
-enum bt_graph_status bt_graph_add_ports_disconnected_listener(
-               struct bt_graph *graph,
-               bt_graph_ports_disconnected_listener listener, void *data)
-{
-       enum bt_graph_status status = BT_GRAPH_STATUS_OK;
-
-       if (!graph || !listener) {
-               status = BT_GRAPH_STATUS_INVALID;
-               goto end;
-       }
-
-       add_listener(graph->listeners.ports_disconnected, listener, data);
-
-end:
-       return status;
-}
-
-BT_HIDDEN
-void bt_graph_notify_port_added(struct bt_graph *graph, struct bt_port *port)
-{
-       size_t i;
-
-       for (i = 0; i < graph->listeners.port_added->len; i++) {
-               struct bt_graph_listener listener =
-                       g_array_index(graph->listeners.port_added,
-                               struct bt_graph_listener, i);
-               bt_graph_port_added_listener func = listener.func;
-
-               assert(func);
-               func(port, listener.data);
-       }
-}
-
-BT_HIDDEN
-void bt_graph_notify_port_removed(struct bt_graph *graph,
-               struct bt_component *comp, struct bt_port *port)
-{
-       size_t i;
-
-       for (i = 0; i < graph->listeners.port_removed->len; i++) {
-               struct bt_graph_listener listener =
-                       g_array_index(graph->listeners.port_removed,
-                               struct bt_graph_listener, i);
-               bt_graph_port_removed_listener func = listener.func;
-
-               assert(func);
-               func(comp, port, listener.data);
-       }
-}
-
-BT_HIDDEN
-void bt_graph_notify_ports_connected(struct bt_graph *graph,
-               struct bt_port *upstream_port, struct bt_port *downstream_port)
-{
-       size_t i;
-
-       for (i = 0; i < graph->listeners.ports_connected->len; i++) {
-               struct bt_graph_listener listener =
-                       g_array_index(graph->listeners.ports_connected,
-                               struct bt_graph_listener, i);
-               bt_graph_ports_connected_listener func = listener.func;
-
-               assert(func);
-               func(upstream_port, downstream_port, listener.data);
-       }
-}
-
-BT_HIDDEN
-void bt_graph_notify_ports_disconnected(struct bt_graph *graph,
-               struct bt_component *upstream_comp,
-               struct bt_component *downstream_comp,
-               struct bt_port *upstream_port, struct bt_port *downstream_port)
-{
-       size_t i;
-
-       for (i = 0; i < graph->listeners.ports_disconnected->len; i++) {
-               struct bt_graph_listener listener =
-                       g_array_index(graph->listeners.ports_disconnected,
-                               struct bt_graph_listener, i);
-               bt_graph_ports_disconnected_listener func = listener.func;
-
-               assert(func);
-               func(upstream_comp, downstream_comp, upstream_port,
-                       downstream_port, listener.data);
-       }
-}
diff --git a/lib/component/iterator.c b/lib/component/iterator.c
deleted file mode 100644 (file)
index 2956295..0000000
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * iterator.c
- *
- * Babeltrace Notification Iterator
- *
- * Copyright 2015 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/compiler-internal.h>
-#include <babeltrace/ref.h>
-#include <babeltrace/graph/component.h>
-#include <babeltrace/graph/component-source-internal.h>
-#include <babeltrace/graph/component-class-internal.h>
-#include <babeltrace/graph/notification-iterator.h>
-#include <babeltrace/graph/notification-iterator-internal.h>
-#include <babeltrace/graph/notification-internal.h>
-
-static
-void bt_notification_iterator_destroy(struct bt_object *obj)
-{
-       struct bt_notification_iterator *iterator;
-       struct bt_component_class *comp_class;
-
-       assert(obj);
-       iterator = container_of(obj, struct bt_notification_iterator,
-                       base);
-       assert(iterator->component);
-       comp_class = iterator->component->class;
-
-       /* Call user-defined destroy method */
-       switch (comp_class->type) {
-       case BT_COMPONENT_CLASS_TYPE_SOURCE:
-       {
-               struct bt_component_class_source *source_class;
-
-               source_class = container_of(comp_class, struct bt_component_class_source, parent);
-
-               if (source_class->methods.iterator.finalize) {
-                       source_class->methods.iterator.finalize(
-                               bt_private_notification_iterator_from_notification_iterator(iterator));
-               }
-               break;
-       }
-       case BT_COMPONENT_CLASS_TYPE_FILTER:
-       {
-               struct bt_component_class_filter *filter_class;
-
-               filter_class = container_of(comp_class, struct bt_component_class_filter, parent);
-
-               if (filter_class->methods.iterator.finalize) {
-                       filter_class->methods.iterator.finalize(
-                               bt_private_notification_iterator_from_notification_iterator(iterator));
-               }
-               break;
-       }
-       default:
-               /* Unreachable */
-               assert(0);
-       }
-
-       BT_PUT(iterator->current_notification);
-       BT_PUT(iterator->component);
-       g_free(iterator);
-}
-
-BT_HIDDEN
-struct bt_notification_iterator *bt_notification_iterator_create(
-               struct bt_component *component)
-{
-       enum bt_component_class_type type;
-       struct bt_notification_iterator *iterator = NULL;
-
-       if (!component) {
-               goto end;
-       }
-
-       type = bt_component_get_class_type(component);
-       switch (type) {
-       case BT_COMPONENT_CLASS_TYPE_SOURCE:
-       case BT_COMPONENT_CLASS_TYPE_FILTER:
-               break;
-       default:
-               goto end;
-       }
-
-       iterator = g_new0(struct bt_notification_iterator, 1);
-       if (!iterator) {
-               goto end;
-       }
-
-       iterator->component = bt_get(component);
-       bt_object_init(iterator, bt_notification_iterator_destroy);
-end:
-       return iterator;
-}
-
-BT_HIDDEN
-enum bt_notification_iterator_status bt_notification_iterator_validate(
-               struct bt_notification_iterator *iterator)
-{
-       enum bt_notification_iterator_status ret =
-                       BT_NOTIFICATION_ITERATOR_STATUS_OK;
-
-       if (!iterator) {
-               ret = BT_NOTIFICATION_ITERATOR_STATUS_INVAL;
-               goto end;
-       }
-end:
-       return ret;
-}
-
-void *bt_private_notification_iterator_get_user_data(
-               struct bt_private_notification_iterator *private_iterator)
-{
-       struct bt_notification_iterator *iterator =
-               bt_notification_iterator_from_private(private_iterator);
-
-       return iterator ? iterator->user_data : NULL;
-}
-
-enum bt_notification_iterator_status
-bt_private_notification_iterator_set_user_data(
-               struct bt_private_notification_iterator *private_iterator,
-               void *data)
-{
-       enum bt_notification_iterator_status ret =
-                       BT_NOTIFICATION_ITERATOR_STATUS_OK;
-       struct bt_notification_iterator *iterator =
-               bt_notification_iterator_from_private(private_iterator);
-
-       if (!iterator) {
-               ret = BT_NOTIFICATION_ITERATOR_STATUS_INVAL;
-               goto end;
-       }
-
-       iterator->user_data = data;
-end:
-       return ret;
-}
-
-struct bt_notification *bt_notification_iterator_get_notification(
-               struct bt_notification_iterator *iterator)
-{
-       struct bt_notification *notification = NULL;
-
-       if (!iterator) {
-               goto end;
-       }
-
-       notification = bt_get(iterator->current_notification);
-
-end:
-       return notification;
-}
-
-enum bt_notification_iterator_status
-bt_notification_iterator_next(struct bt_notification_iterator *iterator)
-{
-       struct bt_private_notification_iterator *priv_iterator =
-               bt_private_notification_iterator_from_notification_iterator(iterator);
-       bt_component_class_notification_iterator_next_method next_method = NULL;
-       struct bt_notification_iterator_next_return next_return;
-       enum bt_notification_iterator_status status =
-               BT_NOTIFICATION_ITERATOR_STATUS_OK;
-
-       if (!iterator) {
-               status = BT_NOTIFICATION_ITERATOR_STATUS_INVAL;
-               goto end;
-       }
-
-       assert(iterator->component);
-       assert(iterator->component->class);
-
-       switch (iterator->component->class->type) {
-       case BT_COMPONENT_CLASS_TYPE_SOURCE:
-       {
-               struct bt_component_class_source *source_class =
-                       container_of(iterator->component->class,
-                               struct bt_component_class_source, parent);
-
-               assert(source_class->methods.iterator.next);
-               next_method = source_class->methods.iterator.next;
-               break;
-       }
-       case BT_COMPONENT_CLASS_TYPE_FILTER:
-       {
-               struct bt_component_class_filter *filter_class =
-                       container_of(iterator->component->class,
-                               struct bt_component_class_filter, parent);
-
-               assert(filter_class->methods.iterator.next);
-               next_method = filter_class->methods.iterator.next;
-               break;
-       }
-       default:
-               assert(false);
-               break;
-       }
-
-       assert(next_method);
-       next_return = next_method(priv_iterator);
-       if (next_return.status == BT_NOTIFICATION_ITERATOR_STATUS_OK) {
-               if (!next_return.notification) {
-                       status = BT_NOTIFICATION_ITERATOR_STATUS_ERROR;
-                       goto end;
-               }
-
-               BT_MOVE(iterator->current_notification,
-                       next_return.notification);
-               bt_notification_freeze(iterator->current_notification);
-       }
-
-end:
-       return next_return.status;
-}
-
-struct bt_component *bt_notification_iterator_get_component(
-               struct bt_notification_iterator *iterator)
-{
-       return bt_get(iterator->component);
-}
-
-struct bt_private_component *
-bt_private_notification_iterator_get_private_component(
-               struct bt_private_notification_iterator *private_iterator)
-{
-       return bt_private_component_from_component(
-               bt_notification_iterator_get_component(
-                       bt_notification_iterator_from_private(private_iterator)));
-}
-
-enum bt_notification_iterator_status bt_notification_iterator_seek_time(
-               struct bt_notification_iterator *iterator,
-               enum bt_notification_iterator_seek_origin seek_origin,
-               int64_t time)
-{
-       enum bt_notification_iterator_status ret =
-                       BT_NOTIFICATION_ITERATOR_STATUS_UNSUPPORTED;
-       return ret;
-}
diff --git a/lib/component/notification/Makefile.am b/lib/component/notification/Makefile.am
deleted file mode 100644 (file)
index 1b08e68..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-AM_CFLAGS = $(PACKAGE_CFLAGS) -I$(top_srcdir)/include
-
-noinst_LTLIBRARIES = libcomponent-notification.la
-
-# Plug-in system library
-libcomponent_notification_la_SOURCES = \
-       notification.c \
-       packet.c \
-       event.c \
-       stream.c \
-       heap.c \
-       inactivity.c
diff --git a/lib/component/notification/event.c b/lib/component/notification/event.c
deleted file mode 100644 (file)
index a9fbf48..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Babeltrace Plug-in Event Notification
- *
- * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/compiler-internal.h>
-#include <babeltrace/ctf-ir/event.h>
-#include <babeltrace/ctf-ir/event-internal.h>
-#include <babeltrace/ctf-ir/event-class.h>
-#include <babeltrace/ctf-ir/stream-class.h>
-#include <babeltrace/ctf-ir/trace.h>
-#include <babeltrace/graph/clock-class-priority-map.h>
-#include <babeltrace/graph/notification-event-internal.h>
-
-static
-void bt_notification_event_destroy(struct bt_object *obj)
-{
-       struct bt_notification_event *notification =
-                       (struct bt_notification_event *) obj;
-
-       BT_PUT(notification->event);
-       BT_PUT(notification->cc_prio_map);
-       g_free(notification);
-}
-
-static
-bool validate_clock_classes(struct bt_notification_event *notif)
-{
-       /*
-        * For each clock class found in the event's trace, get the
-        * event's clock value for this clock class, and if it exists,
-        * make sure that this clock class has a priority in the
-        * notification's clock class priority map.
-        */
-       bool is_valid = true;
-       int ret;
-       int count;
-       size_t i;
-       struct bt_ctf_event_class *event_class = NULL;
-       struct bt_ctf_stream_class *stream_class = NULL;
-       struct bt_ctf_trace *trace = NULL;
-       uint64_t prio;
-
-       event_class = bt_ctf_event_get_class(notif->event);
-       assert(event_class);
-       stream_class = bt_ctf_event_class_get_stream_class(event_class);
-       assert(stream_class);
-       trace = bt_ctf_stream_class_get_trace(stream_class);
-       assert(trace);
-       count = bt_ctf_trace_get_clock_class_count(trace);
-       assert(count >= 0);
-
-       for (i = 0; i < count; i++) {
-               struct bt_ctf_clock_class *clock_class =
-                       bt_ctf_trace_get_clock_class(trace, i);
-
-               assert(clock_class);
-               ret = bt_clock_class_priority_map_get_clock_class_priority(
-                       notif->cc_prio_map, clock_class, &prio);
-               bt_put(clock_class);
-               if (ret) {
-                       is_valid = false;
-                       goto end;
-               }
-       }
-
-end:
-       bt_put(trace);
-       bt_put(stream_class);
-       bt_put(event_class);
-       return is_valid;
-}
-
-struct bt_notification *bt_notification_event_create(struct bt_ctf_event *event,
-               struct bt_clock_class_priority_map *cc_prio_map)
-{
-       struct bt_notification_event *notification = NULL;
-
-       if (!event || !cc_prio_map) {
-               goto error;
-       }
-
-       if (!bt_ctf_event_borrow_packet(event)) {
-               goto error;
-       }
-
-       notification = g_new0(struct bt_notification_event, 1);
-       if (!notification) {
-               goto error;
-       }
-       bt_notification_init(&notification->parent,
-                       BT_NOTIFICATION_TYPE_EVENT,
-                       bt_notification_event_destroy);
-       notification->event = bt_get(event);
-       notification->cc_prio_map = bt_get(cc_prio_map);
-       if (!validate_clock_classes(notification)) {
-               goto error;
-       }
-
-       bt_ctf_event_freeze(notification->event);
-       return &notification->parent;
-error:
-       bt_put(notification);
-       return NULL;
-}
-
-struct bt_ctf_event *bt_notification_event_get_event(
-               struct bt_notification *notification)
-{
-       struct bt_ctf_event *event = NULL;
-       struct bt_notification_event *event_notification;
-
-       if (bt_notification_get_type(notification) !=
-                       BT_NOTIFICATION_TYPE_EVENT) {
-               goto end;
-       }
-       event_notification = container_of(notification,
-                       struct bt_notification_event, parent);
-       event = bt_get(event_notification->event);
-end:
-       return event;
-}
-
-extern struct bt_clock_class_priority_map *
-bt_notification_event_get_clock_class_priority_map(
-               struct bt_notification *notification)
-{
-       struct bt_clock_class_priority_map *cc_prio_map = NULL;
-       struct bt_notification_event *event_notification;
-
-       if (bt_notification_get_type(notification) !=
-                       BT_NOTIFICATION_TYPE_EVENT) {
-               goto end;
-       }
-
-       event_notification = container_of(notification,
-                       struct bt_notification_event, parent);
-       cc_prio_map = bt_get(event_notification->cc_prio_map);
-end:
-       return cc_prio_map;
-}
diff --git a/lib/component/notification/heap.c b/lib/component/notification/heap.c
deleted file mode 100644 (file)
index fc0bce8..0000000
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Babeltrace - CTF notification priority heap
- *
- * Static-sized priority heap containing pointers. Based on CLRS,
- * chapter 6.
- *
- * Copyright (c) 2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- * Copyright (c) 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <assert.h>
-#include <stddef.h>
-#include <babeltrace/compiler-internal.h>
-#include <babeltrace/graph/notification-heap-internal.h>
-
-#ifdef DEBUG_HEAP
-static
-void check_heap(struct bt_notification_heap *heap)
-{
-       size_t i;
-
-       if (!heap->count) {
-               return;
-       }
-
-       for (i = 1; i < heap->count; i++) {
-               assert(!heap->compare(g_ptr_array_index(heap->ptrs, i),
-                               g_ptr_array_index(heap->ptrs, 0),
-                               heap->compare_data));
-       }
-}
-#else
-void check_heap(struct bt_notification_heap *heap)
-{
-}
-#endif
-
-static
-size_t parent(size_t i)
-{
-       return (i - 1) >> 1;
-}
-
-static
-size_t left(size_t i)
-{
-       return (i << 1) + 1;
-}
-
-static
-size_t right(size_t i)
-{
-       return (i << 1) + 2;
-}
-
-/*
- * Copy of heap->ptrs pointer is invalid after heap_grow.
- */
-static
-int heap_grow(struct bt_notification_heap *heap, size_t new_len)
-{
-       size_t alloc_len;
-
-       if (likely(heap->ptrs->len >= new_len)) {
-               goto end;
-       }
-
-        alloc_len = max_t(size_t, new_len, heap->ptrs->len << 1);
-       g_ptr_array_set_size(heap->ptrs, alloc_len);
-end:
-       return 0;
-}
-
-static
-int heap_set_count(struct bt_notification_heap *heap, size_t new_count)
-{
-       int ret = 0;
-
-       ret = heap_grow(heap, new_count);
-       if (unlikely(ret)) {
-               goto end;
-       }
-       heap->count = new_count;
-end:
-       return ret;
-}
-
-static
-void heapify(struct bt_notification_heap *heap, size_t i)
-{
-       struct bt_notification **ptrs =
-                       (struct bt_notification **) heap->ptrs->pdata;
-
-       for (;;) {
-               void *tmp;
-               size_t l, r, largest;
-
-               l = left(i);
-               r = right(i);
-               if (l < heap->count && heap->compare(ptrs[l], ptrs[i],
-                               heap->compare_data)) {
-                       largest = l;
-               } else {
-                       largest = i;
-               }
-               if (r < heap->count && heap->compare(ptrs[r], ptrs[largest],
-                               heap->compare_data)) {
-                       largest = r;
-               }
-               if (unlikely(largest == i)) {
-                       break;
-               }
-               tmp = ptrs[i];
-               ptrs[i] = ptrs[largest];
-               ptrs[largest] = tmp;
-               i = largest;
-       }
-       check_heap(heap);
-}
-
-static
-struct bt_notification *heap_replace_max(struct bt_notification_heap *heap,
-               struct bt_notification *notification)
-{
-       struct bt_notification *res = NULL;
-
-       if (unlikely(!heap->count)) {
-               (void) heap_set_count(heap, 1);
-               g_ptr_array_index(heap->ptrs, 0) = notification;
-               check_heap(heap);
-               goto end;
-       }
-
-       /* Replace the current max and heapify. */
-       res = g_ptr_array_index(heap->ptrs, 0);
-       g_ptr_array_index(heap->ptrs, 0) = notification;
-       heapify(heap, 0);
-end:
-       return res;
-}
-
-static
-void bt_notification_heap_destroy(struct bt_object *obj)
-{
-       struct bt_notification_heap *heap = container_of(obj,
-                       struct bt_notification_heap, base);
-
-       if (heap->ptrs) {
-               size_t i;
-
-               for (i = 0; i < heap->count; i++) {
-                       bt_put(g_ptr_array_index(heap->ptrs, i));
-               }
-               g_ptr_array_free(heap->ptrs, TRUE);
-       }
-       g_free(heap);
-}
-
-struct bt_notification_heap *bt_notification_heap_create(
-               bt_notification_time_compare_func comparator, void *user_data)
-{
-       struct bt_notification_heap *heap = NULL;
-
-       if (!comparator) {
-               goto end;
-       }
-
-       heap = g_new0(struct bt_notification_heap, 1);
-       if (!heap) {
-               goto end;
-       }
-
-       bt_object_init(&heap->base, bt_notification_heap_destroy);
-       heap->ptrs = g_ptr_array_new();
-       if (!heap->ptrs) {
-               BT_PUT(heap);
-               goto end;
-       }
-
-       heap->compare = comparator;
-       heap->compare_data = user_data;
-end:
-       return heap;
-}
-
-struct bt_notification *bt_notification_heap_peek(
-               struct bt_notification_heap *heap)
-{
-       check_heap(heap);
-       return bt_get(likely(heap->count) ?
-                       g_ptr_array_index(heap->ptrs, 0) : NULL);
-}
-
-int bt_notification_heap_insert(struct bt_notification_heap *heap,
-               struct bt_notification *notification)
-{
-       int ret;
-       size_t pos;
-        struct bt_notification **ptrs;
-
-       ret = heap_set_count(heap, heap->count + 1);
-       if (unlikely(ret)) {
-               goto end;
-       }
-
-       ptrs = (struct bt_notification **) heap->ptrs->pdata;
-       pos = heap->count - 1;
-       while (pos > 0 && heap->compare(notification, ptrs[parent(pos)],
-                       heap->compare_data)) {
-               /* Move parent down until we find the right spot. */
-               ptrs[pos] = ptrs[parent(pos)];
-               pos = parent(pos);
-       }
-       ptrs[pos] = bt_get(notification);
-       check_heap(heap);
-end:
-       return ret;
-}
-
-struct bt_notification *bt_notification_heap_pop(
-               struct bt_notification_heap *heap)
-{
-        struct bt_notification *ret = NULL;
-
-       switch (heap->count) {
-       case 0:
-               goto end;
-       case 1:
-               (void) heap_set_count(heap, 0);
-               ret = g_ptr_array_index(heap->ptrs, 0);
-               goto end;
-       }
-       /*
-        * Shrink, replace the current max by previous last entry and heapify.
-        */
-       heap_set_count(heap, heap->count - 1);
-       /* count changed. previous last entry is at heap->count. */
-       ret = heap_replace_max(heap, g_ptr_array_index(heap->ptrs,
-                       heap->count));
-end:
-       /*
-        * Not taking a supplementary reference since we are relinquishing our
-        * own to the caller.
-        */
-       return ret;
-}
diff --git a/lib/component/notification/inactivity.c b/lib/component/notification/inactivity.c
deleted file mode 100644 (file)
index 4807395..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright 2017 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/object-internal.h>
-#include <babeltrace/compiler-internal.h>
-#include <babeltrace/ctf-ir/clock-class.h>
-#include <babeltrace/graph/clock-class-priority-map.h>
-#include <babeltrace/graph/notification-internal.h>
-#include <babeltrace/graph/notification-inactivity-internal.h>
-
-static
-void bt_notification_inactivity_destroy(struct bt_object *obj)
-{
-       struct bt_notification_inactivity *notification =
-                       (struct bt_notification_inactivity *) obj;
-
-       bt_put(notification->cc_prio_map);
-
-       if (notification->clock_values) {
-               g_hash_table_destroy(notification->clock_values);
-       }
-
-       g_free(notification);
-}
-
-struct bt_notification *bt_notification_inactivity_create(
-               struct bt_clock_class_priority_map *cc_prio_map)
-{
-       struct bt_notification_inactivity *notification;
-       struct bt_notification *ret_notif = NULL;
-
-       if (!cc_prio_map) {
-               goto error;
-       }
-
-       notification = g_new0(struct bt_notification_inactivity, 1);
-       if (!notification) {
-               goto error;
-       }
-       bt_notification_init(&notification->parent,
-                       BT_NOTIFICATION_TYPE_INACTIVITY,
-                       bt_notification_inactivity_destroy);
-       ret_notif = &notification->parent;
-       notification->clock_values = g_hash_table_new_full(g_direct_hash,
-                       g_direct_equal, bt_put, bt_put);
-       if (!notification->clock_values) {
-               goto error;
-       }
-
-       notification->cc_prio_map = bt_get(cc_prio_map);
-       goto end;
-
-error:
-       BT_PUT(ret_notif);
-
-end:
-       return ret_notif;
-}
-
-extern struct bt_clock_class_priority_map *
-bt_notification_inactivity_get_clock_class_priority_map(
-               struct bt_notification *notification)
-{
-       struct bt_clock_class_priority_map *cc_prio_map = NULL;
-       struct bt_notification_inactivity *inactivity_notification;
-
-       if (bt_notification_get_type(notification) !=
-                       BT_NOTIFICATION_TYPE_INACTIVITY) {
-               goto end;
-       }
-
-       inactivity_notification = container_of(notification,
-                       struct bt_notification_inactivity, parent);
-       cc_prio_map = bt_get(inactivity_notification->cc_prio_map);
-end:
-       return cc_prio_map;
-}
-
-struct bt_ctf_clock_value *bt_notification_inactivity_get_clock_value(
-               struct bt_notification *notification,
-               struct bt_ctf_clock_class *clock_class)
-{
-       struct bt_ctf_clock_value *clock_value = NULL;
-       struct bt_notification_inactivity *inactivity_notification;
-
-       if (!notification || !clock_class) {
-               goto end;
-       }
-
-       if (bt_notification_get_type(notification) !=
-                       BT_NOTIFICATION_TYPE_INACTIVITY) {
-               goto end;
-       }
-
-       inactivity_notification = container_of(notification,
-                       struct bt_notification_inactivity, parent);
-       clock_value = g_hash_table_lookup(inactivity_notification->clock_values,
-               clock_class);
-       bt_get(clock_value);
-
-end:
-       return clock_value;
-}
-
-int bt_notification_inactivity_set_clock_value(
-               struct bt_notification *notification,
-               struct bt_ctf_clock_value *clock_value)
-{
-       int ret = 0;
-       uint64_t prio;
-       struct bt_ctf_clock_class *clock_class = NULL;
-       struct bt_notification_inactivity *inactivity_notification;
-
-       if (!notification || !clock_value || notification->frozen) {
-               ret = -1;
-               goto end;
-       }
-
-       if (bt_notification_get_type(notification) !=
-                       BT_NOTIFICATION_TYPE_INACTIVITY) {
-               goto end;
-       }
-
-       inactivity_notification = container_of(notification,
-                       struct bt_notification_inactivity, parent);
-       clock_class = bt_ctf_clock_value_get_class(clock_value);
-       ret = bt_clock_class_priority_map_get_clock_class_priority(
-               inactivity_notification->cc_prio_map, clock_class, &prio);
-       if (ret) {
-               /*
-                * Clock value's class is not mapped to a priority
-                * within the scope of this notification.
-                */
-               goto end;
-       }
-
-       g_hash_table_insert(inactivity_notification->clock_values,
-               clock_class, bt_get(clock_value));
-       clock_class = NULL;
-
-end:
-       bt_put(clock_class);
-       return ret;
-}
diff --git a/lib/component/notification/notification.c b/lib/component/notification/notification.c
deleted file mode 100644 (file)
index 9dc64d7..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Babeltrace Plug-in Notification
- *
- * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/graph/notification-internal.h>
-
-BT_HIDDEN
-void bt_notification_init(struct bt_notification *notification,
-               enum bt_notification_type type,
-               bt_object_release_func release)
-{
-       assert(type > BT_NOTIFICATION_TYPE_ALL &&
-                       type < BT_NOTIFICATION_TYPE_NR);
-       notification->type = type;
-       bt_object_init(&notification->base, release);
-}
-
-enum bt_notification_type bt_notification_get_type(
-               struct bt_notification *notification)
-{
-       return notification ? notification->type : BT_NOTIFICATION_TYPE_UNKNOWN;
-}
-
-struct bt_ctf_stream *bt_notification_get_stream(
-               struct bt_notification *notification)
-{
-       struct bt_ctf_stream *stream = NULL;
-
-       if (!notification || !notification->get_stream) {
-               goto end;
-       }
-
-       stream = notification->get_stream(notification);
-end:
-       return stream;
-}
diff --git a/lib/component/notification/packet.c b/lib/component/notification/packet.c
deleted file mode 100644 (file)
index fa6a0ee..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Babeltrace Plug-in Packet-related Notifications
- *
- * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/compiler-internal.h>
-#include <babeltrace/graph/notification-packet-internal.h>
-
-static
-void bt_notification_packet_begin_destroy(struct bt_object *obj)
-{
-       struct bt_notification_packet_begin *notification =
-                       (struct bt_notification_packet_begin *) obj;
-
-       BT_PUT(notification->packet);
-       g_free(notification);
-}
-
-static
-void bt_notification_packet_end_destroy(struct bt_object *obj)
-{
-       struct bt_notification_packet_end *notification =
-                       (struct bt_notification_packet_end *) obj;
-
-       BT_PUT(notification->packet);
-       g_free(notification);
-}
-
-struct bt_notification *bt_notification_packet_begin_create(
-               struct bt_ctf_packet *packet)
-{
-       struct bt_notification_packet_begin *notification;
-
-       if (!packet) {
-               goto error;
-       }
-
-       notification = g_new0(struct bt_notification_packet_begin, 1);
-       bt_notification_init(&notification->parent,
-                       BT_NOTIFICATION_TYPE_PACKET_BEGIN,
-                       bt_notification_packet_begin_destroy);
-       notification->packet = bt_get(packet);
-       return &notification->parent;
-error:
-       return NULL;
-}
-
-struct bt_ctf_packet *bt_notification_packet_begin_get_packet(
-               struct bt_notification *notification)
-{
-       struct bt_ctf_packet *ret = NULL;
-       struct bt_notification_packet_begin *packet_begin;
-
-       if (notification->type != BT_NOTIFICATION_TYPE_PACKET_BEGIN) {
-               goto end;
-       }
-
-       packet_begin = container_of(notification,
-                       struct bt_notification_packet_begin, parent);
-       ret = bt_get(packet_begin->packet);
-end:
-       return ret;
-}
-
-struct bt_notification *bt_notification_packet_end_create(
-               struct bt_ctf_packet *packet)
-{
-       struct bt_notification_packet_end *notification;
-
-       if (!packet) {
-               goto error;
-       }
-
-       notification = g_new0(struct bt_notification_packet_end, 1);
-       bt_notification_init(&notification->parent,
-                       BT_NOTIFICATION_TYPE_PACKET_END,
-                       bt_notification_packet_end_destroy);
-       notification->packet = bt_get(packet);
-       return &notification->parent;
-error:
-       return NULL;
-}
-
-struct bt_ctf_packet *bt_notification_packet_end_get_packet(
-               struct bt_notification *notification)
-{
-       struct bt_ctf_packet *ret = NULL;
-       struct bt_notification_packet_end *packet_end;
-
-       if (notification->type != BT_NOTIFICATION_TYPE_PACKET_END) {
-               goto end;
-       }
-
-       packet_end = container_of(notification,
-                       struct bt_notification_packet_end, parent);
-       ret = bt_get(packet_end->packet);
-end:
-       return ret;
-}
diff --git a/lib/component/notification/stream.c b/lib/component/notification/stream.c
deleted file mode 100644 (file)
index 68b9bcd..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Babeltrace Plug-in Stream-related Notifications
- *
- * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/compiler-internal.h>
-#include <babeltrace/graph/notification-stream-internal.h>
-
-static
-void bt_notification_stream_end_destroy(struct bt_object *obj)
-{
-       struct bt_notification_stream_end *notification =
-                       (struct bt_notification_stream_end *) obj;
-
-       BT_PUT(notification->stream);
-       g_free(notification);
-}
-
-struct bt_notification *bt_notification_stream_end_create(
-               struct bt_ctf_stream *stream)
-{
-       struct bt_notification_stream_end *notification;
-
-       if (!stream) {
-               goto error;
-       }
-
-       notification = g_new0(struct bt_notification_stream_end, 1);
-       bt_notification_init(&notification->parent,
-                       BT_NOTIFICATION_TYPE_STREAM_END,
-                       bt_notification_stream_end_destroy);
-       notification->stream = bt_get(stream);
-       return &notification->parent;
-error:
-       return NULL;
-}
-
-struct bt_ctf_packet *bt_notification_stream_end_get_stream(
-               struct bt_notification *notification)
-{
-       struct bt_notification_stream_end *stream_end;
-
-       stream_end = container_of(notification,
-                       struct bt_notification_stream_end, parent);
-       return bt_get(stream_end->stream);
-}
diff --git a/lib/component/port.c b/lib/component/port.c
deleted file mode 100644 (file)
index c0d5e06..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * port.c
- *
- * Babeltrace Port
- *
- * Copyright 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/graph/component-internal.h>
-#include <babeltrace/graph/port-internal.h>
-#include <babeltrace/graph/connection-internal.h>
-#include <babeltrace/object-internal.h>
-#include <babeltrace/compiler-internal.h>
-
-static
-void bt_port_destroy(struct bt_object *obj)
-{
-       struct bt_port *port = container_of(obj, struct bt_port, base);
-
-       if (port->name) {
-               g_string_free(port->name, TRUE);
-       }
-       g_free(port);
-}
-
-struct bt_port *bt_port_from_private_port(
-               struct bt_private_port *private_port)
-{
-       return bt_get(bt_port_from_private(private_port));
-}
-
-BT_HIDDEN
-struct bt_port *bt_port_create(struct bt_component *parent_component,
-               enum bt_port_type type, const char *name)
-{
-       struct bt_port *port = NULL;
-
-       assert(name);
-       assert(parent_component);
-       assert(type == BT_PORT_TYPE_INPUT || type == BT_PORT_TYPE_OUTPUT);
-
-       if (strlen(name) == 0) {
-               goto end;
-       }
-
-       port = g_new0(struct bt_port, 1);
-       if (!port) {
-               goto end;
-       }
-
-       bt_object_init(port, bt_port_destroy);
-       port->name = g_string_new(name);
-       if (!port->name) {
-               BT_PUT(port);
-               goto end;
-       }
-
-       port->type = type;
-
-       bt_object_set_parent(port, &parent_component->base);
-end:
-       return port;
-}
-
-const char *bt_port_get_name(struct bt_port *port)
-{
-       return port ? port->name->str : NULL;
-}
-
-enum bt_port_type bt_port_get_type(struct bt_port *port)
-{
-       return port ? port->type : BT_PORT_TYPE_UNKOWN;
-}
-
-struct bt_connection *bt_port_get_connection(struct bt_port *port)
-{
-       struct bt_connection *connection = NULL;
-
-       if (!port || !port->connection) {
-               goto end;
-       }
-
-       connection = bt_get(port->connection);
-end:
-       return connection;
-}
-
-struct bt_component *bt_port_get_component(struct bt_port *port)
-{
-       return (struct bt_component *) bt_object_get_parent(port);
-}
-
-struct bt_private_connection *bt_private_port_get_private_connection(
-               struct bt_private_port *private_port)
-{
-       return bt_private_connection_from_connection(bt_port_get_connection(
-               bt_port_from_private(private_port)));
-}
-
-struct bt_private_component *bt_private_port_get_private_component(
-               struct bt_private_port *private_port)
-{
-       return bt_private_component_from_component(bt_port_get_component(
-               bt_port_from_private(private_port)));
-}
-
-BT_HIDDEN
-void bt_port_set_connection(struct bt_port *port,
-               struct bt_connection *connection)
-{
-       /*
-        * Don't take a reference on connection as its existence is
-        * guaranteed by the existence of the graph in which the
-        * connection exists.
-        */
-       port->connection = connection;
-}
-
-int bt_private_port_remove_from_component(
-               struct bt_private_port *private_port)
-{
-       int ret = 0;
-       struct bt_port *port = bt_port_from_private(private_port);
-       struct bt_component *comp = NULL;
-
-       if (!port) {
-               ret = -1;
-               goto end;
-       }
-
-       comp = (void *) bt_object_get_parent(port);
-       ret = bt_component_remove_port(comp, port);
-
-end:
-       bt_put(comp);
-       return ret;
-}
-
-int bt_port_disconnect(struct bt_port *port)
-{
-       int ret = 0;
-
-       if (!port) {
-               ret = -1;
-               goto end;
-       }
-
-       if (port->connection) {
-               bt_connection_disconnect_ports(port->connection);
-       }
-
-end:
-       return ret;
-}
-
-int bt_port_is_connected(struct bt_port *port)
-{
-       int ret;
-
-       if (!port) {
-               ret = -1;
-               goto end;
-       }
-
-       ret = port->connection ? 1 : 0;
-
-end:
-       return ret;
-}
-
-int bt_private_port_set_user_data(
-               struct bt_private_port *private_port, void *user_data)
-{
-       int ret = 0;
-
-       if (!private_port) {
-               ret = -1;
-               goto end;
-       }
-
-       bt_port_from_private(private_port)->user_data = user_data;
-
-end:
-       return ret;
-}
-
-void *bt_private_port_get_user_data(
-               struct bt_private_port *private_port)
-{
-       return private_port ?
-               bt_port_from_private(private_port)->user_data : NULL;
-}
diff --git a/lib/component/sink.c b/lib/component/sink.c
deleted file mode 100644 (file)
index 49bd840..0000000
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * sink.c
- *
- * Babeltrace Sink Component
- *
- * Copyright 2015 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/compiler-internal.h>
-#include <babeltrace/values.h>
-#include <babeltrace/graph/component-sink-internal.h>
-#include <babeltrace/graph/component-internal.h>
-#include <babeltrace/graph/notification.h>
-
-BT_HIDDEN
-enum bt_component_status bt_component_sink_validate(
-               struct bt_component *component)
-{
-       enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
-
-       if (!component) {
-               ret = BT_COMPONENT_STATUS_INVALID;
-               goto end;
-       }
-
-       if (!component->class) {
-               ret = BT_COMPONENT_STATUS_INVALID;
-               goto end;
-       }
-
-       if (component->class->type != BT_COMPONENT_CLASS_TYPE_SINK) {
-               ret = BT_COMPONENT_STATUS_INVALID;
-               goto end;
-       }
-end:
-       return ret;
-}
-
-BT_HIDDEN
-void bt_component_sink_destroy(struct bt_component *component)
-{
-}
-
-BT_HIDDEN
-struct bt_component *bt_component_sink_create(
-               struct bt_component_class *class, struct bt_value *params)
-{
-       struct bt_component_sink *sink = NULL;
-
-       sink = g_new0(struct bt_component_sink, 1);
-       if (!sink) {
-               goto end;
-       }
-
-end:
-       return sink ? &sink->parent : NULL;
-}
-
-BT_HIDDEN
-enum bt_component_status bt_component_sink_consume(
-               struct bt_component *component)
-{
-       enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
-       struct bt_component_class_sink *sink_class = NULL;
-
-       if (!component) {
-               ret = BT_COMPONENT_STATUS_INVALID;
-               goto end;
-       }
-
-       if (bt_component_get_class_type(component) != BT_COMPONENT_CLASS_TYPE_SINK) {
-               ret = BT_COMPONENT_STATUS_UNSUPPORTED;
-               goto end;
-       }
-
-       sink_class = container_of(component->class, struct bt_component_class_sink, parent);
-       assert(sink_class->methods.consume);
-       ret = sink_class->methods.consume(bt_private_component_from_component(component));
-end:
-       return ret;
-}
-
-enum bt_component_status bt_component_sink_get_input_port_count(
-               struct bt_component *component, uint64_t *count)
-{
-       enum bt_component_status status = BT_COMPONENT_STATUS_OK;
-
-       if (!component || !count ||
-                       component->class->type != BT_COMPONENT_CLASS_TYPE_SINK) {
-               status = BT_COMPONENT_STATUS_INVALID;
-               goto end;
-       }
-
-       *count = bt_component_get_input_port_count(component);
-end:
-       return status;
-}
-
-struct bt_port *bt_component_sink_get_input_port(
-               struct bt_component *component, const char *name)
-{
-       struct bt_port *port = NULL;
-
-       if (!component || !name ||
-                       component->class->type != BT_COMPONENT_CLASS_TYPE_SINK) {
-               goto end;
-       }
-
-       port = bt_component_get_input_port(component, name);
-end:
-       return port;
-}
-
-struct bt_port *bt_component_sink_get_input_port_at_index(
-               struct bt_component *component, int index)
-{
-       struct bt_port *port = NULL;
-
-       if (!component ||
-                       component->class->type != BT_COMPONENT_CLASS_TYPE_SINK) {
-               goto end;
-       }
-
-       port = bt_component_get_input_port_at_index(component, index);
-end:
-       return port;
-}
-
-struct bt_port *bt_component_sink_get_default_input_port(
-               struct bt_component *component)
-{
-       return bt_component_sink_get_input_port(component,
-                       DEFAULT_INPUT_PORT_NAME);
-}
-
-struct bt_private_port *
-bt_private_component_sink_get_input_private_port_at_index(
-               struct bt_private_component *private_component, int index)
-{
-       return bt_private_port_from_port(
-               bt_component_sink_get_input_port_at_index(
-                       bt_component_from_private(private_component), index));
-}
-
-struct bt_private_port *bt_private_component_sink_get_default_input_private_port(
-               struct bt_private_component *private_component)
-{
-       return bt_private_port_from_port(
-               bt_component_sink_get_default_input_port(
-                       bt_component_from_private(private_component)));
-}
-
-struct bt_private_port *bt_private_component_sink_add_input_private_port(
-               struct bt_private_component *private_component,
-               const char *name)
-{
-       struct bt_port *port = NULL;
-       struct bt_component *component =
-               bt_component_from_private(private_component);
-
-       if (!component ||
-                       component->class->type != BT_COMPONENT_CLASS_TYPE_SINK) {
-               goto end;
-       }
-
-       port = bt_component_add_input_port(component, name);
-end:
-       return bt_private_port_from_port(port);
-}
diff --git a/lib/component/source.c b/lib/component/source.c
deleted file mode 100644 (file)
index 0c4f181..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * source.c
- *
- * Babeltrace Source Component
- *
- * Copyright 2015 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <babeltrace/ref.h>
-#include <babeltrace/compiler-internal.h>
-#include <babeltrace/graph/component-source-internal.h>
-#include <babeltrace/graph/component-internal.h>
-#include <babeltrace/graph/port-internal.h>
-#include <babeltrace/graph/notification-iterator.h>
-#include <babeltrace/graph/notification-iterator-internal.h>
-
-BT_HIDDEN
-enum bt_component_status bt_component_source_validate(
-               struct bt_component *component)
-{
-       enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
-
-       if (!component) {
-               ret = BT_COMPONENT_STATUS_INVALID;
-               goto end;
-       }
-
-       if (!component->class) {
-               ret = BT_COMPONENT_STATUS_INVALID;
-               goto end;
-       }
-
-       if (component->class->type != BT_COMPONENT_CLASS_TYPE_SOURCE) {
-               ret = BT_COMPONENT_STATUS_INVALID;
-               goto end;
-       }
-
-end:
-       return ret;
-}
-
-BT_HIDDEN
-void bt_component_source_destroy(struct bt_component *component)
-{
-}
-
-BT_HIDDEN
-struct bt_component *bt_component_source_create(
-               struct bt_component_class *class, struct bt_value *params)
-{
-       struct bt_component_source *source = NULL;
-
-       source = g_new0(struct bt_component_source, 1);
-       if (!source) {
-               goto end;
-       }
-
-end:
-       return source ? &source->parent : NULL;
-}
-
-enum bt_component_status bt_component_source_get_output_port_count(
-               struct bt_component *component, uint64_t *count)
-{
-       enum bt_component_status status = BT_COMPONENT_STATUS_OK;
-
-       if (!component || !count ||
-                       component->class->type != BT_COMPONENT_CLASS_TYPE_SOURCE) {
-               status = BT_COMPONENT_STATUS_INVALID;
-               goto end;
-       }
-
-       *count = bt_component_get_output_port_count(component);
-end:
-       return status;
-}
-
-struct bt_port *bt_component_source_get_output_port(
-               struct bt_component *component, const char *name)
-{
-       struct bt_port *port = NULL;
-
-       if (!component || !name ||
-                       component->class->type != BT_COMPONENT_CLASS_TYPE_SOURCE) {
-               goto end;
-       }
-
-       port = bt_component_get_output_port(component, name);
-end:
-       return port;
-}
-
-struct bt_port *bt_component_source_get_output_port_at_index(
-               struct bt_component *component, int index)
-{
-       struct bt_port *port = NULL;
-
-       if (!component ||
-                       component->class->type != BT_COMPONENT_CLASS_TYPE_SOURCE) {
-               goto end;
-       }
-
-       port = bt_component_get_output_port_at_index(component, index);
-end:
-       return port;
-}
-
-struct bt_port *bt_component_source_get_default_output_port(
-               struct bt_component *component)
-{
-       return bt_component_source_get_output_port(component,
-                       DEFAULT_OUTPUT_PORT_NAME);
-}
-
-struct bt_private_port *bt_private_component_source_get_output_private_port(
-               struct bt_private_component *private_component,
-               const char *name)
-{
-       return bt_private_port_from_port(bt_component_source_get_output_port(
-               bt_component_from_private(private_component), name));
-}
-
-struct bt_private_port *
-bt_private_component_source_get_output_private_port_at_index(
-               struct bt_private_component *private_component, int index)
-{
-       return bt_private_port_from_port(
-               bt_component_source_get_output_port_at_index(
-                       bt_component_from_private(private_component), index));
-}
-
-struct bt_private_port *bt_private_component_source_get_default_output_private_port(
-               struct bt_private_component *private_component)
-{
-       return bt_private_port_from_port(
-               bt_component_source_get_default_output_port(
-                       bt_component_from_private(private_component)));
-}
-
-struct bt_private_port *bt_private_component_source_add_output_private_port(
-               struct bt_private_component *private_component,
-               const char *name)
-{
-       struct bt_port *port = NULL;
-       struct bt_component *component =
-               bt_component_from_private(private_component);
-
-       if (!component ||
-                       component->class->type != BT_COMPONENT_CLASS_TYPE_SOURCE) {
-               goto end;
-       }
-
-       port = bt_component_add_output_port(component, name);
-end:
-       return bt_private_port_from_port(port);
-}
diff --git a/lib/graph/Makefile.am b/lib/graph/Makefile.am
new file mode 100644 (file)
index 0000000..09bb179
--- /dev/null
@@ -0,0 +1,21 @@
+AM_CFLAGS = $(PACKAGE_CFLAGS) -I$(top_srcdir)/include
+
+SUBDIRS = notification
+
+noinst_LTLIBRARIES = libgraph.la
+
+# Graph library
+libgraph_la_SOURCES = \
+       clock-class-priority-map.c \
+       component.c \
+       component-class.c \
+       graph.c \
+       connection.c \
+       port.c \
+       source.c \
+       sink.c \
+       filter.c \
+       iterator.c
+
+libgraph_la_LIBADD = \
+       notification/libgraph-notification.la
diff --git a/lib/graph/clock-class-priority-map.c b/lib/graph/clock-class-priority-map.c
new file mode 100644 (file)
index 0000000..f905519
--- /dev/null
@@ -0,0 +1,267 @@
+/*
+ * clock-class-priority-map.c
+ *
+ * Copyright 2017 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/graph/clock-class-priority-map.h>
+#include <babeltrace/graph/clock-class-priority-map-internal.h>
+#include <babeltrace/ctf-ir/clock-class.h>
+#include <babeltrace/ctf-ir/clock-class-internal.h>
+#include <babeltrace/babeltrace-internal.h>
+#include <babeltrace/compiler-internal.h>
+#include <babeltrace/ref.h>
+#include <glib.h>
+
+static
+void bt_clock_class_priority_map_destroy(struct bt_object *obj)
+{
+       struct bt_clock_class_priority_map *cc_prio_map = (void *) obj;
+
+       if (!cc_prio_map) {
+               return;
+       }
+
+       if (cc_prio_map->entries) {
+               g_ptr_array_free(cc_prio_map->entries, TRUE);
+       }
+
+       if (cc_prio_map->prios) {
+               g_hash_table_destroy(cc_prio_map->prios);
+       }
+
+       g_free(cc_prio_map);
+}
+
+struct bt_clock_class_priority_map *bt_clock_class_priority_map_create()
+{
+       struct bt_clock_class_priority_map *cc_prio_map = NULL;
+
+       cc_prio_map = g_new0(struct bt_clock_class_priority_map, 1);
+       if (!cc_prio_map) {
+               goto error;
+       }
+
+       bt_object_init(cc_prio_map, bt_clock_class_priority_map_destroy);
+       cc_prio_map->entries = g_ptr_array_new_with_free_func(
+               (GDestroyNotify) bt_put);
+       if (!cc_prio_map->entries) {
+               goto error;
+       }
+
+       cc_prio_map->prios = g_hash_table_new_full(g_direct_hash,
+               g_direct_equal, NULL, (GDestroyNotify) g_free);
+       if (!cc_prio_map->entries) {
+               goto error;
+       }
+
+       goto end;
+
+error:
+       BT_PUT(cc_prio_map);
+
+end:
+       return cc_prio_map;
+}
+
+int bt_clock_class_priority_map_get_clock_class_count(
+               struct bt_clock_class_priority_map *cc_prio_map)
+{
+       int ret = -1;
+
+       if (!cc_prio_map) {
+               goto end;
+       }
+
+       ret = (int) cc_prio_map->entries->len;
+
+end:
+       return ret;
+}
+
+struct bt_ctf_clock_class *bt_clock_class_priority_map_get_clock_class(
+               struct bt_clock_class_priority_map *cc_prio_map,
+               unsigned int index)
+{
+       struct bt_ctf_clock_class *clock_class = NULL;
+
+       if (!cc_prio_map || index >= cc_prio_map->entries->len) {
+               goto end;
+       }
+
+       clock_class = g_ptr_array_index(cc_prio_map->entries, index);
+       bt_get(clock_class);
+
+end:
+       return clock_class;
+}
+
+struct bt_ctf_clock_class *bt_clock_class_priority_map_get_clock_class_by_name(
+               struct bt_clock_class_priority_map *cc_prio_map,
+               const char *name)
+{
+       size_t i;
+       struct bt_ctf_clock_class *clock_class = NULL;
+
+       if (!cc_prio_map || !name) {
+               goto end;
+       }
+
+       for (i = 0; i < cc_prio_map->entries->len; i++) {
+               struct bt_ctf_clock_class *cur_cc =
+                       g_ptr_array_index(cc_prio_map->entries, i);
+               // FIXME when available: use bt_ctf_clock_class_get_name()
+               const char *cur_cc_name =
+                       cur_cc->name ? cur_cc->name->str : NULL;
+
+               if (!cur_cc_name) {
+                       goto end;
+               }
+
+               if (strcmp(cur_cc_name, name) == 0) {
+                       clock_class = bt_get(cur_cc);
+                       goto end;
+               }
+       }
+
+end:
+       return clock_class;
+}
+
+
+struct clock_class_prio {
+       uint64_t prio;
+       struct bt_ctf_clock_class *clock_class;
+};
+
+static
+void current_highest_prio_gh_func(gpointer key, gpointer value,
+               gpointer user_data)
+{
+       struct clock_class_prio *func_data = user_data;
+       uint64_t *prio = value;
+
+       if (*prio <= func_data->prio) {
+               func_data->prio = *prio;
+               func_data->clock_class = key;
+       }
+}
+
+static
+struct clock_class_prio bt_ctf_clock_class_priority_map_current_highest_prio(
+               struct bt_clock_class_priority_map *cc_prio_map)
+{
+       struct clock_class_prio func_data = {
+               .prio = -1ULL,
+               .clock_class = NULL,
+       };
+
+       g_hash_table_foreach(cc_prio_map->prios, current_highest_prio_gh_func,
+               &func_data);
+       return func_data;
+}
+
+struct bt_ctf_clock_class *
+bt_clock_class_priority_map_get_highest_priority_clock_class(
+               struct bt_clock_class_priority_map *cc_prio_map)
+{
+       struct bt_ctf_clock_class *clock_class = NULL;
+
+       if (!cc_prio_map) {
+               goto end;
+       }
+
+       clock_class = bt_get(cc_prio_map->highest_prio_cc);
+
+end:
+       return clock_class;
+}
+
+int bt_clock_class_priority_map_get_clock_class_priority(
+               struct bt_clock_class_priority_map *cc_prio_map,
+               struct bt_ctf_clock_class *clock_class, uint64_t *priority)
+{
+       int ret = 0;
+       uint64_t *prio;
+
+       if (!cc_prio_map || !clock_class || !priority) {
+               ret = -1;
+               goto end;
+       }
+
+       prio = g_hash_table_lookup(cc_prio_map->prios, clock_class);
+       if (!prio) {
+               ret = -1;
+               goto end;
+       }
+
+       *priority = *prio;
+
+end:
+       return ret;
+}
+
+int bt_clock_class_priority_map_add_clock_class(
+               struct bt_clock_class_priority_map *cc_prio_map,
+               struct bt_ctf_clock_class *clock_class, uint64_t priority)
+{
+       int ret = 0;
+       uint64_t *prio_ptr = NULL;
+       struct clock_class_prio cc_prio;
+
+       // FIXME when available: check
+       // bt_ctf_clock_class_is_valid(clock_class)
+       if (!cc_prio_map) {
+               ret = -1;
+               goto end;
+       }
+
+       /* Check for duplicate clock classes */
+       prio_ptr = g_hash_table_lookup(cc_prio_map->prios, clock_class);
+       if (prio_ptr) {
+               prio_ptr = NULL;
+               ret = -1;
+               goto end;
+       }
+
+       prio_ptr = g_new(uint64_t, 1);
+       if (!prio_ptr) {
+               ret = -1;
+               goto end;
+       }
+
+       *prio_ptr = priority;
+       bt_get(clock_class);
+       g_ptr_array_add(cc_prio_map->entries, clock_class);
+       g_hash_table_insert(cc_prio_map->prios, clock_class, prio_ptr);
+       prio_ptr = NULL;
+       cc_prio = bt_ctf_clock_class_priority_map_current_highest_prio(
+               cc_prio_map);
+       assert(cc_prio.clock_class);
+       cc_prio_map->highest_prio_cc = cc_prio.clock_class;
+
+end:
+       if (prio_ptr) {
+               g_free(prio_ptr);
+       }
+
+       return ret;
+}
diff --git a/lib/graph/component-class.c b/lib/graph/component-class.c
new file mode 100644 (file)
index 0000000..4585b1f
--- /dev/null
@@ -0,0 +1,544 @@
+/*
+ * component-class.c
+ *
+ * Babeltrace Plugin Component Class
+ *
+ * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/compiler-internal.h>
+#include <babeltrace/graph/component-class-internal.h>
+#include <babeltrace/ref.h>
+#include <stdbool.h>
+#include <glib.h>
+
+static
+void bt_component_class_destroy(struct bt_object *obj)
+{
+       struct bt_component_class *class;
+       int i;
+
+       assert(obj);
+       class = container_of(obj, struct bt_component_class, base);
+
+       /* Call destroy listeners in reverse registration order */
+       for (i = class->destroy_listeners->len - 1; i >= 0; i--) {
+               struct bt_component_class_destroy_listener *listener =
+                       &g_array_index(class->destroy_listeners,
+                               struct bt_component_class_destroy_listener,
+                               i);
+
+               listener->func(class, listener->data);
+       }
+
+       if (class->name) {
+               g_string_free(class->name, TRUE);
+       }
+       if (class->description) {
+               g_string_free(class->description, TRUE);
+       }
+       if (class->help) {
+               g_string_free(class->help, TRUE);
+       }
+       if (class->destroy_listeners) {
+               g_array_free(class->destroy_listeners, TRUE);
+       }
+
+       g_free(class);
+}
+
+static
+int bt_component_class_init(struct bt_component_class *class,
+               enum bt_component_class_type type, const char *name)
+{
+       int ret = 0;
+
+       bt_object_init(class, bt_component_class_destroy);
+       class->type = type;
+       class->name = g_string_new(name);
+       if (!class->name) {
+               goto error;
+       }
+
+       class->description = g_string_new(NULL);
+       if (!class->description) {
+               goto error;
+       }
+
+       class->help = g_string_new(NULL);
+       if (!class->help) {
+               goto error;
+       }
+
+       class->destroy_listeners = g_array_new(FALSE, TRUE,
+               sizeof(struct bt_component_class_destroy_listener));
+       if (!class->destroy_listeners) {
+               goto error;
+       }
+
+       goto end;
+
+error:
+       BT_PUT(class);
+       ret = -1;
+
+end:
+       return ret;
+}
+
+struct bt_component_class *bt_component_class_source_create(const char *name,
+               bt_component_class_notification_iterator_next_method notification_iterator_next_method)
+{
+       struct bt_component_class_source *source_class = NULL;
+       int ret;
+
+       if (!name || !notification_iterator_next_method) {
+               goto end;
+       }
+
+       source_class = g_new0(struct bt_component_class_source, 1);
+       if (!source_class) {
+               goto end;
+       }
+
+       ret = bt_component_class_init(&source_class->parent,
+               BT_COMPONENT_CLASS_TYPE_SOURCE, name);
+       if (ret) {
+               /*
+                * If bt_component_class_init() fails, the component
+                * class is put, therefore its memory is already
+                * freed.
+                */
+               source_class = NULL;
+               goto end;
+       }
+
+       source_class->methods.iterator.next = notification_iterator_next_method;
+
+end:
+       return &source_class->parent;
+}
+
+struct bt_component_class *bt_component_class_filter_create(const char *name,
+               bt_component_class_notification_iterator_next_method notification_iterator_next_method)
+{
+       struct bt_component_class_filter *filter_class = NULL;
+       int ret;
+
+       if (!name || !notification_iterator_next_method) {
+               goto end;
+       }
+
+       filter_class = g_new0(struct bt_component_class_filter, 1);
+       if (!filter_class) {
+               goto end;
+       }
+
+       ret = bt_component_class_init(&filter_class->parent,
+               BT_COMPONENT_CLASS_TYPE_FILTER, name);
+       if (ret) {
+               /*
+                * If bt_component_class_init() fails, the component
+                * class is put, therefore its memory is already
+                * freed.
+                */
+               filter_class = NULL;
+               goto end;
+       }
+
+       filter_class->methods.iterator.next = notification_iterator_next_method;
+
+end:
+       return &filter_class->parent;
+}
+
+struct bt_component_class *bt_component_class_sink_create(const char *name,
+               bt_component_class_sink_consume_method consume_method)
+{
+       struct bt_component_class_sink *sink_class = NULL;
+       int ret;
+
+       if (!name || !consume_method) {
+               goto end;
+       }
+
+       sink_class = g_new0(struct bt_component_class_sink, 1);
+       if (!sink_class) {
+               goto end;
+       }
+
+       ret = bt_component_class_init(&sink_class->parent,
+               BT_COMPONENT_CLASS_TYPE_SINK, name);
+       if (ret) {
+               /*
+                * If bt_component_class_init() fails, the component
+                * class is put, therefore its memory is already
+                * freed.
+                */
+               sink_class = NULL;
+               goto end;
+       }
+
+       sink_class->methods.consume = consume_method;
+
+end:
+       return &sink_class->parent;
+}
+
+int bt_component_class_set_init_method(
+               struct bt_component_class *component_class,
+               bt_component_class_init_method init_method)
+{
+       int ret = 0;
+
+       if (!component_class || component_class->frozen || !init_method) {
+               ret = -1;
+               goto end;
+       }
+
+       component_class->methods.init = init_method;
+
+end:
+       return ret;
+}
+
+int bt_component_class_set_query_method(
+               struct bt_component_class *component_class,
+               bt_component_class_query_method query_method)
+{
+       int ret = 0;
+
+       if (!component_class || component_class->frozen || !query_method) {
+               ret = -1;
+               goto end;
+       }
+
+       component_class->methods.query = query_method;
+
+end:
+       return ret;
+}
+
+int bt_component_class_set_accept_port_connection_method(
+               struct bt_component_class *component_class,
+               bt_component_class_accept_port_connection_method method)
+{
+       int ret = 0;
+
+       if (!component_class || component_class->frozen || !method) {
+               ret = -1;
+               goto end;
+       }
+
+       component_class->methods.accept_port_connection = method;
+
+end:
+       return ret;
+}
+
+int bt_component_class_set_port_disconnected_method(
+               struct bt_component_class *component_class,
+               bt_component_class_port_disconnected_method method)
+{
+       int ret = 0;
+
+       if (!component_class || component_class->frozen || !method) {
+               ret = -1;
+               goto end;
+       }
+
+       component_class->methods.port_disconnected = method;
+
+end:
+       return ret;
+}
+
+int bt_component_class_set_finalize_method(
+               struct bt_component_class *component_class,
+               bt_component_class_finalize_method finalize_method)
+{
+       int ret = 0;
+
+       if (!component_class || component_class->frozen || !finalize_method) {
+               ret = -1;
+               goto end;
+       }
+
+       component_class->methods.finalize = finalize_method;
+
+end:
+       return ret;
+}
+
+int bt_component_class_source_set_notification_iterator_init_method(
+               struct bt_component_class *component_class,
+               bt_component_class_notification_iterator_init_method notification_iterator_init_method)
+{
+       struct bt_component_class_source *source_class;
+       int ret = 0;
+
+       if (!component_class || component_class->frozen ||
+                       !notification_iterator_init_method ||
+                       component_class->type != BT_COMPONENT_CLASS_TYPE_SOURCE) {
+               ret = -1;
+               goto end;
+       }
+
+       source_class = container_of(component_class,
+               struct bt_component_class_source, parent);
+       source_class->methods.iterator.init = notification_iterator_init_method;
+
+end:
+       return ret;
+}
+
+int bt_component_class_source_set_notification_iterator_finalize_method(
+               struct bt_component_class *component_class,
+               bt_component_class_notification_iterator_finalize_method notification_iterator_finalize_method)
+{
+       struct bt_component_class_source *source_class;
+       int ret = 0;
+
+       if (!component_class || component_class->frozen ||
+                       !notification_iterator_finalize_method ||
+                       component_class->type != BT_COMPONENT_CLASS_TYPE_SOURCE) {
+               ret = -1;
+               goto end;
+       }
+
+       source_class = container_of(component_class,
+               struct bt_component_class_source, parent);
+       source_class->methods.iterator.finalize =
+               notification_iterator_finalize_method;
+
+end:
+       return ret;
+}
+
+int bt_component_class_source_set_notification_iterator_seek_time_method(
+               struct bt_component_class *component_class,
+               bt_component_class_notification_iterator_seek_time_method notification_iterator_seek_time_method)
+{
+       struct bt_component_class_source *source_class;
+       int ret = 0;
+
+       if (!component_class || component_class->frozen ||
+                       !notification_iterator_seek_time_method ||
+                       component_class->type != BT_COMPONENT_CLASS_TYPE_SOURCE) {
+               ret = -1;
+               goto end;
+       }
+
+       source_class = container_of(component_class,
+               struct bt_component_class_source, parent);
+       source_class->methods.iterator.seek_time =
+               notification_iterator_seek_time_method;
+
+end:
+       return ret;
+}
+
+int bt_component_class_filter_set_notification_iterator_init_method(
+               struct bt_component_class *component_class,
+               bt_component_class_notification_iterator_init_method notification_iterator_init_method)
+{
+       struct bt_component_class_filter *filter_class;
+       int ret = 0;
+
+       if (!component_class || component_class->frozen ||
+                       !notification_iterator_init_method ||
+                       component_class->type != BT_COMPONENT_CLASS_TYPE_FILTER) {
+               ret = -1;
+               goto end;
+       }
+
+       filter_class = container_of(component_class,
+               struct bt_component_class_filter, parent);
+       filter_class->methods.iterator.init = notification_iterator_init_method;
+
+end:
+       return ret;
+}
+
+int bt_component_class_filter_set_notification_iterator_finalize_method(
+               struct bt_component_class *component_class,
+               bt_component_class_notification_iterator_finalize_method notification_iterator_finalize_method)
+{
+       struct bt_component_class_filter *filter_class;
+       int ret = 0;
+
+       if (!component_class || component_class->frozen ||
+                       !notification_iterator_finalize_method ||
+                       component_class->type != BT_COMPONENT_CLASS_TYPE_FILTER) {
+               ret = -1;
+               goto end;
+       }
+
+       filter_class = container_of(component_class,
+               struct bt_component_class_filter, parent);
+       filter_class->methods.iterator.finalize =
+               notification_iterator_finalize_method;
+
+end:
+       return ret;
+}
+
+int bt_component_class_filter_set_notification_iterator_seek_time_method(
+               struct bt_component_class *component_class,
+               bt_component_class_notification_iterator_seek_time_method notification_iterator_seek_time_method)
+{
+       struct bt_component_class_filter *filter_class;
+       int ret = 0;
+
+       if (!component_class || component_class->frozen ||
+                       !notification_iterator_seek_time_method ||
+                       component_class->type != BT_COMPONENT_CLASS_TYPE_FILTER) {
+               ret = -1;
+               goto end;
+       }
+
+       filter_class = container_of(component_class,
+               struct bt_component_class_filter, parent);
+       filter_class->methods.iterator.seek_time =
+               notification_iterator_seek_time_method;
+
+end:
+       return ret;
+}
+
+int bt_component_class_set_description(
+               struct bt_component_class *component_class,
+               const char *description)
+{
+       int ret = 0;
+
+       if (!component_class || component_class->frozen || !description) {
+               ret = -1;
+               goto end;
+       }
+
+       g_string_assign(component_class->description, description);
+
+end:
+       return ret;
+}
+
+int bt_component_class_set_help(
+               struct bt_component_class *component_class,
+               const char *help)
+{
+       int ret = 0;
+
+       if (!component_class || component_class->frozen || !help) {
+               ret = -1;
+               goto end;
+       }
+
+       g_string_assign(component_class->help, help);
+
+end:
+       return ret;
+}
+
+const char *bt_component_class_get_name(
+               struct bt_component_class *component_class)
+{
+       return component_class ? component_class->name->str : NULL;
+}
+
+enum bt_component_class_type bt_component_class_get_type(
+               struct bt_component_class *component_class)
+{
+       return component_class ? component_class->type :
+                       BT_COMPONENT_CLASS_TYPE_UNKNOWN;
+}
+
+const char *bt_component_class_get_description(
+               struct bt_component_class *component_class)
+{
+       return component_class && component_class->description &&
+               component_class->description->str[0] != '\0' ?
+               component_class->description->str : NULL;
+}
+
+const char *bt_component_class_get_help(
+               struct bt_component_class *component_class)
+{
+       return component_class && component_class->help &&
+               component_class->help->str[0] != '\0' ?
+               component_class->help->str : NULL;
+}
+
+BT_HIDDEN
+int bt_component_class_add_destroy_listener(struct bt_component_class *class,
+               bt_component_class_destroy_listener_func func, void *data)
+{
+       int ret = 0;
+       struct bt_component_class_destroy_listener listener;
+
+       if (!class || class->frozen || !func) {
+               ret = -1;
+               goto end;
+       }
+
+       listener.func = func;
+       listener.data = data;
+       g_array_append_val(class->destroy_listeners, listener);
+
+end:
+       return ret;
+}
+
+int bt_component_class_freeze(
+               struct bt_component_class *component_class)
+{
+       int ret = 0;
+
+       if (!component_class) {
+               ret = -1;
+               goto end;
+       }
+
+       component_class->frozen = true;
+
+end:
+       return ret;
+}
+
+struct bt_value *bt_component_class_query(
+               struct bt_component_class *component_class,
+               const char *object, struct bt_value *params)
+{
+       struct bt_value *results = NULL;
+
+       if (!component_class || !object || !params ||
+                       !component_class->methods.query) {
+               goto end;
+       }
+
+       results = component_class->methods.query(component_class,
+               object, params);
+
+end:
+       return results;
+}
diff --git a/lib/graph/component.c b/lib/graph/component.c
new file mode 100644 (file)
index 0000000..9b996f6
--- /dev/null
@@ -0,0 +1,568 @@
+/*
+ * component.c
+ *
+ * Babeltrace Plugin Component
+ *
+ * Copyright 2015 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/graph/private-component.h>
+#include <babeltrace/graph/component.h>
+#include <babeltrace/graph/component-internal.h>
+#include <babeltrace/graph/component-class-internal.h>
+#include <babeltrace/graph/component-source-internal.h>
+#include <babeltrace/graph/component-filter-internal.h>
+#include <babeltrace/graph/component-sink-internal.h>
+#include <babeltrace/graph/private-connection.h>
+#include <babeltrace/graph/connection-internal.h>
+#include <babeltrace/graph/graph-internal.h>
+#include <babeltrace/graph/notification-iterator-internal.h>
+#include <babeltrace/graph/private-notification-iterator.h>
+#include <babeltrace/babeltrace-internal.h>
+#include <babeltrace/compiler-internal.h>
+#include <babeltrace/ref.h>
+
+static
+struct bt_component * (* const component_create_funcs[])(
+               struct bt_component_class *, struct bt_value *) = {
+       [BT_COMPONENT_CLASS_TYPE_SOURCE] = bt_component_source_create,
+       [BT_COMPONENT_CLASS_TYPE_SINK] = bt_component_sink_create,
+       [BT_COMPONENT_CLASS_TYPE_FILTER] = bt_component_filter_create,
+};
+
+static
+void (*component_destroy_funcs[])(struct bt_component *) = {
+       [BT_COMPONENT_CLASS_TYPE_SOURCE] = bt_component_source_destroy,
+       [BT_COMPONENT_CLASS_TYPE_SINK] = bt_component_sink_destroy,
+       [BT_COMPONENT_CLASS_TYPE_FILTER] = bt_component_filter_destroy,
+};
+
+static
+enum bt_component_status (* const component_validation_funcs[])(
+               struct bt_component *) = {
+       [BT_COMPONENT_CLASS_TYPE_SOURCE] = bt_component_source_validate,
+       [BT_COMPONENT_CLASS_TYPE_SINK] = bt_component_sink_validate,
+       [BT_COMPONENT_CLASS_TYPE_FILTER] = bt_component_filter_validate,
+};
+
+static
+void bt_component_destroy(struct bt_object *obj)
+{
+       struct bt_component *component = NULL;
+       struct bt_component_class *component_class = NULL;
+
+       if (!obj) {
+               return;
+       }
+
+       component = container_of(obj, struct bt_component, base);
+       component_class = component->class;
+
+       /*
+        * User data is destroyed first, followed by the concrete component
+        * instance.
+        */
+       if (component->class->methods.finalize) {
+               component->class->methods.finalize(
+                       bt_private_component_from_component(component));
+       }
+
+       if (component->destroy) {
+               component->destroy(component);
+       }
+
+       if (component->input_ports) {
+               g_ptr_array_free(component->input_ports, TRUE);
+       }
+
+       if (component->output_ports) {
+               g_ptr_array_free(component->output_ports, TRUE);
+       }
+
+       g_string_free(component->name, TRUE);
+       bt_put(component_class);
+       g_free(component);
+}
+
+struct bt_component *bt_component_from_private_component(
+               struct bt_private_component *private_component)
+{
+       return bt_get(bt_component_from_private(private_component));
+}
+
+enum bt_component_class_type bt_component_get_class_type(
+               struct bt_component *component)
+{
+       return component ? component->class->type : BT_COMPONENT_CLASS_TYPE_UNKNOWN;
+}
+
+static
+struct bt_port *bt_component_add_port(
+               struct bt_component *component, GPtrArray *ports,
+               enum bt_port_type port_type, const char *name)
+{
+       size_t i;
+       struct bt_port *new_port = NULL;
+       struct bt_graph *graph = NULL;
+
+       if (!name || strlen(name) == 0) {
+               goto end;
+       }
+
+       /* Look for a port having the same name. */
+       for (i = 0; i < ports->len; i++) {
+               const char *port_name;
+               struct bt_port *port = g_ptr_array_index(
+                               ports, i);
+
+               port_name = bt_port_get_name(port);
+               if (!port_name) {
+                       continue;
+               }
+
+               if (!strcmp(name, port_name)) {
+                       /* Port name clash, abort. */
+                       goto end;
+               }
+       }
+
+       new_port = bt_port_create(component, port_type, name);
+       if (!new_port) {
+               goto end;
+       }
+
+       /*
+        * No name clash, add the port.
+        * The component is now the port's parent; it should _not_
+        * hold a reference to the port since the port's lifetime
+        * is now protected by the component's own lifetime.
+        */
+       g_ptr_array_add(ports, new_port);
+
+       /*
+        * Notify the graph's creator that a new port was added.
+        */
+       graph = bt_component_get_graph(component);
+       if (graph) {
+               bt_graph_notify_port_added(graph, new_port);
+               BT_PUT(graph);
+       }
+
+end:
+       return new_port;
+}
+
+BT_HIDDEN
+uint64_t bt_component_get_input_port_count(struct bt_component *comp)
+{
+       assert(comp);
+       return comp->input_ports->len;
+}
+
+BT_HIDDEN
+uint64_t bt_component_get_output_port_count(struct bt_component *comp)
+{
+       assert(comp);
+       return comp->output_ports->len;
+}
+
+struct bt_component *bt_component_create_with_init_method_data(
+               struct bt_component_class *component_class, const char *name,
+               struct bt_value *params, void *init_method_data)
+{
+       int ret;
+       struct bt_component *component = NULL;
+       enum bt_component_class_type type;
+       struct bt_port *default_port = NULL;
+
+       if (!component_class) {
+               goto end;
+       }
+
+       type = bt_component_class_get_type(component_class);
+       if (type <= BT_COMPONENT_CLASS_TYPE_UNKNOWN ||
+                       type > BT_COMPONENT_CLASS_TYPE_FILTER) {
+               goto end;
+       }
+
+       component = component_create_funcs[type](component_class, params);
+       if (!component) {
+               goto end;
+       }
+
+       bt_object_init(component, bt_component_destroy);
+       component->class = bt_get(component_class);
+       component->destroy = component_destroy_funcs[type];
+       component->name = g_string_new(name);
+       if (!component->name) {
+               BT_PUT(component);
+               goto end;
+       }
+
+       component->input_ports = g_ptr_array_new_with_free_func(
+               bt_object_release);
+       if (!component->input_ports) {
+               BT_PUT(component);
+               goto end;
+       }
+
+       component->output_ports = g_ptr_array_new_with_free_func(
+               bt_object_release);
+       if (!component->output_ports) {
+               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,
+                       component->output_ports, BT_PORT_TYPE_OUTPUT,
+                       DEFAULT_OUTPUT_PORT_NAME);
+               if (!default_port) {
+                       BT_PUT(component);
+                       goto end;
+               }
+
+               BT_PUT(default_port);
+       }
+
+       if (type == BT_COMPONENT_CLASS_TYPE_FILTER ||
+                       type == BT_COMPONENT_CLASS_TYPE_SINK) {
+               default_port = bt_component_add_port(component,
+                       component->input_ports, BT_PORT_TYPE_INPUT,
+                       DEFAULT_INPUT_PORT_NAME);
+               if (!default_port) {
+                       BT_PUT(component);
+                       goto end;
+               }
+
+               BT_PUT(default_port);
+       }
+
+       component->initializing = true;
+
+       if (component_class->methods.init) {
+               ret = component_class->methods.init(
+                       bt_private_component_from_component(component), params,
+                       init_method_data);
+               component->initializing = false;
+               if (ret != BT_COMPONENT_STATUS_OK) {
+                       BT_PUT(component);
+                       goto end;
+               }
+       }
+
+       component->initializing = false;
+       ret = component_validation_funcs[type](component);
+       if (ret != BT_COMPONENT_STATUS_OK) {
+               BT_PUT(component);
+               goto end;
+       }
+
+       bt_component_class_freeze(component->class);
+end:
+       bt_put(default_port);
+       return component;
+}
+
+struct bt_component *bt_component_create(
+               struct bt_component_class *component_class, const char *name,
+               struct bt_value *params)
+{
+       return bt_component_create_with_init_method_data(component_class, name,
+               params, NULL);
+}
+
+const char *bt_component_get_name(struct bt_component *component)
+{
+       const char *ret = NULL;
+
+       if (!component) {
+               goto end;
+       }
+
+       ret = component->name->len == 0 ? NULL : component->name->str;
+end:
+       return ret;
+}
+
+enum bt_component_status bt_component_set_name(struct bt_component *component,
+               const char *name)
+{
+       enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
+
+       if (!component || !name || name[0] == '\0') {
+               ret = BT_COMPONENT_STATUS_INVALID;
+               goto end;
+       }
+
+       g_string_assign(component->name, name);
+end:
+       return ret;
+}
+
+struct bt_component_class *bt_component_get_class(
+               struct bt_component *component)
+{
+       return component ? bt_get(component->class) : NULL;
+}
+
+void *bt_private_component_get_user_data(
+               struct bt_private_component *private_component)
+{
+       struct bt_component *component =
+               bt_component_from_private(private_component);
+
+       return component ? component->user_data : NULL;
+}
+
+enum bt_component_status bt_private_component_set_user_data(
+               struct bt_private_component *private_component,
+               void *data)
+{
+       struct bt_component *component =
+               bt_component_from_private(private_component);
+       enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
+
+       if (!component || !component->initializing) {
+               ret = BT_COMPONENT_STATUS_INVALID;
+               goto end;
+       }
+
+       component->user_data = data;
+end:
+       return ret;
+}
+
+BT_HIDDEN
+void bt_component_set_graph(struct bt_component *component,
+               struct bt_graph *graph)
+{
+       struct bt_object *parent = bt_object_get_parent(&component->base);
+
+       assert(!parent || parent == &graph->base);
+       if (!parent) {
+               bt_object_set_parent(component, &graph->base);
+       }
+       bt_put(parent);
+}
+
+struct bt_graph *bt_component_get_graph(
+               struct bt_component *component)
+{
+       return (struct bt_graph *) bt_object_get_parent(&component->base);
+}
+
+static
+struct bt_port *bt_component_get_port(GPtrArray *ports, const char *name)
+{
+       size_t i;
+       struct bt_port *ret_port = NULL;
+
+       assert(name);
+
+       for (i = 0; i < ports->len; i++) {
+               struct bt_port *port = g_ptr_array_index(ports, i);
+               const char *port_name = bt_port_get_name(port);
+
+               if (!port_name) {
+                       continue;
+               }
+
+               if (!strcmp(name, port_name)) {
+                       ret_port = bt_get(port);
+                       break;
+               }
+       }
+
+       return ret_port;
+}
+
+BT_HIDDEN
+struct bt_port *bt_component_get_input_port(struct bt_component *comp,
+               const char *name)
+{
+       assert(comp);
+
+       return bt_component_get_port(comp->input_ports, name);
+}
+
+BT_HIDDEN
+struct bt_port *bt_component_get_output_port(struct bt_component *comp,
+               const char *name)
+{
+       assert(comp);
+
+       return bt_component_get_port(comp->output_ports, name);
+}
+
+static
+struct bt_port *bt_component_get_port_at_index(GPtrArray *ports, int index)
+{
+       struct bt_port *port = NULL;
+
+       if (index < 0 || index >= ports->len) {
+               goto end;
+       }
+
+       port = bt_get(g_ptr_array_index(ports, index));
+end:
+       return port;
+}
+
+BT_HIDDEN
+struct bt_port *bt_component_get_input_port_at_index(struct bt_component *comp,
+               int index)
+{
+       assert(comp);
+
+       return bt_component_get_port_at_index(comp->input_ports, index);
+}
+
+BT_HIDDEN
+struct bt_port *bt_component_get_output_port_at_index(struct bt_component *comp,
+               int index)
+{
+       assert(comp);
+
+       return bt_component_get_port_at_index(comp->output_ports, index);
+}
+
+BT_HIDDEN
+struct bt_port *bt_component_add_input_port(
+               struct bt_component *component, const char *name)
+{
+       return bt_component_add_port(component, component->input_ports,
+               BT_PORT_TYPE_INPUT, name);
+}
+
+BT_HIDDEN
+struct bt_port *bt_component_add_output_port(
+               struct bt_component *component, const char *name)
+{
+       return bt_component_add_port(component, component->output_ports,
+               BT_PORT_TYPE_OUTPUT, name);
+}
+
+static
+void bt_component_remove_port_at_index(struct bt_component *component,
+               GPtrArray *ports, size_t index)
+{
+       struct bt_port *port;
+       struct bt_graph *graph;
+
+       assert(ports);
+       assert(index < ports->len);
+       port = g_ptr_array_index(ports, index);
+
+       /* Disconnect both ports of this port's connection, if any */
+       if (port->connection) {
+               bt_connection_disconnect_ports(port->connection);
+       }
+
+       /* Remove from parent's array of ports (weak refs) */
+       g_ptr_array_remove_index(ports, index);
+
+       /* Detach port from its component parent */
+       BT_PUT(port->base.parent);
+
+       /*
+        * Notify the graph's creator that a port is removed.
+        */
+       graph = bt_component_get_graph(component);
+       if (graph) {
+               bt_graph_notify_port_removed(graph, component, port);
+               BT_PUT(graph);
+       }
+}
+
+BT_HIDDEN
+enum bt_component_status bt_component_remove_port(
+               struct bt_component *component, struct bt_port *port)
+{
+       size_t i;
+       enum bt_component_status status = BT_COMPONENT_STATUS_OK;
+       GPtrArray *ports = NULL;
+
+       if (!component || !port) {
+               status = BT_COMPONENT_STATUS_INVALID;
+               goto end;
+       }
+
+       if (bt_port_get_type(port) == BT_PORT_TYPE_INPUT) {
+               ports = component->input_ports;
+       } else if (bt_port_get_type(port) == BT_PORT_TYPE_OUTPUT) {
+               ports = component->output_ports;
+       }
+
+       assert(ports);
+
+       for (i = 0; i < ports->len; i++) {
+               struct bt_port *cur_port = g_ptr_array_index(ports, i);
+
+               if (cur_port == port) {
+                       bt_component_remove_port_at_index(component,
+                               ports, i);
+                       goto end;
+               }
+       }
+
+       status = BT_COMPONENT_STATUS_NOT_FOUND;
+end:
+       return status;
+}
+
+BT_HIDDEN
+enum bt_component_status bt_component_accept_port_connection(
+               struct bt_component *comp, struct bt_port *self_port,
+               struct bt_port *other_port)
+{
+       enum bt_component_status status = BT_COMPONENT_STATUS_OK;
+
+       assert(comp);
+       assert(self_port);
+       assert(other_port);
+
+       if (comp->class->methods.accept_port_connection) {
+               status = comp->class->methods.accept_port_connection(
+                       bt_private_component_from_component(comp),
+                       bt_private_port_from_port(self_port),
+                       other_port);
+       }
+
+       return status;
+}
+
+BT_HIDDEN
+void bt_component_port_disconnected(struct bt_component *comp,
+               struct bt_port *port)
+{
+       assert(comp);
+       assert(port);
+
+       if (comp->class->methods.port_disconnected) {
+               comp->class->methods.port_disconnected(
+                       bt_private_component_from_component(comp),
+                       bt_private_port_from_port(port));
+       }
+}
diff --git a/lib/graph/connection.c b/lib/graph/connection.c
new file mode 100644 (file)
index 0000000..986303e
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+ * connection.c
+ *
+ * Babeltrace Connection
+ *
+ * Copyright 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/graph/notification-iterator-internal.h>
+#include <babeltrace/graph/component-internal.h>
+#include <babeltrace/graph/component-source-internal.h>
+#include <babeltrace/graph/component-filter-internal.h>
+#include <babeltrace/graph/connection-internal.h>
+#include <babeltrace/graph/private-connection.h>
+#include <babeltrace/graph/graph-internal.h>
+#include <babeltrace/graph/port-internal.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/compiler-internal.h>
+#include <glib.h>
+
+static
+void bt_connection_destroy(struct bt_object *obj)
+{
+       struct bt_connection *connection = container_of(obj,
+                       struct bt_connection, base);
+
+       /*
+        * No bt_put on ports as a connection only holds _weak_ references
+        * to them.
+        */
+       g_free(connection);
+}
+
+struct bt_connection *bt_connection_from_private_connection(
+               struct bt_private_connection *private_connection)
+{
+       return bt_get(bt_connection_from_private(private_connection));
+}
+
+BT_HIDDEN
+struct bt_connection *bt_connection_create(
+               struct bt_graph *graph,
+               struct bt_port *upstream_port,
+               struct bt_port *downstream_port)
+{
+       struct bt_connection *connection = NULL;
+
+       if (bt_port_get_type(upstream_port) != BT_PORT_TYPE_OUTPUT) {
+               goto end;
+       }
+       if (bt_port_get_type(downstream_port) != BT_PORT_TYPE_INPUT) {
+               goto end;
+       }
+
+       connection = g_new0(struct bt_connection, 1);
+       if (!connection) {
+               goto end;
+       }
+
+       bt_object_init(connection, bt_connection_destroy);
+       /* Weak references are taken, see comment in header. */
+       connection->upstream_port = upstream_port;
+       connection->downstream_port = downstream_port;
+       bt_port_set_connection(upstream_port, connection);
+       bt_port_set_connection(downstream_port, connection);
+       bt_object_set_parent(connection, &graph->base);
+end:
+       return connection;
+}
+
+BT_HIDDEN
+void bt_connection_disconnect_ports(struct bt_connection *conn)
+{
+       struct bt_component *downstream_comp = NULL;
+       struct bt_component *upstream_comp = NULL;
+       struct bt_port *downstream_port = conn->downstream_port;
+       struct bt_port *upstream_port = conn->upstream_port;
+       struct bt_graph *graph = (void *) bt_object_get_parent(conn);
+
+       if (downstream_port) {
+               downstream_comp = bt_port_get_component(downstream_port);
+               bt_port_set_connection(downstream_port, NULL);
+               conn->downstream_port = NULL;
+       }
+
+       if (upstream_port) {
+               upstream_comp = bt_port_get_component(upstream_port);
+               bt_port_set_connection(upstream_port, NULL);
+               conn->upstream_port = NULL;
+       }
+
+       if (downstream_comp) {
+               bt_component_port_disconnected(downstream_comp,
+                       downstream_port);
+       }
+
+       if (upstream_comp) {
+               bt_component_port_disconnected(upstream_comp, upstream_port);
+       }
+
+       assert(graph);
+       bt_graph_notify_ports_disconnected(graph, upstream_comp,
+               downstream_comp, upstream_port, downstream_port);
+       bt_put(downstream_comp);
+       bt_put(upstream_comp);
+       bt_put(graph);
+}
+
+struct bt_port *bt_connection_get_upstream_port(
+               struct bt_connection *connection)
+{
+       return connection ? bt_get(connection->upstream_port) : NULL;
+}
+
+struct bt_port *bt_connection_get_downstream_port(
+               struct bt_connection *connection)
+{
+       return connection ? bt_get(connection->downstream_port) : NULL;
+}
+
+struct bt_notification_iterator *
+bt_private_connection_create_notification_iterator(
+               struct bt_private_connection *private_connection)
+{
+       enum bt_notification_iterator_status ret_iterator;
+       enum bt_component_class_type upstream_comp_class_type;
+       struct bt_notification_iterator *iterator = NULL;
+       struct bt_port *upstream_port = NULL;
+       struct bt_component *upstream_component = NULL;
+       struct bt_component_class *upstream_comp_class = NULL;
+       struct bt_connection *connection = NULL;
+       bt_component_class_notification_iterator_init_method init_method = NULL;
+
+       if (!private_connection) {
+               goto error;
+       }
+
+       connection = bt_connection_from_private(private_connection);
+
+       if (!connection->upstream_port || !connection->downstream_port) {
+               goto error;
+       }
+
+       upstream_port = connection->upstream_port;
+       assert(upstream_port);
+       upstream_component = bt_port_get_component(upstream_port);
+       assert(upstream_component);
+       upstream_comp_class = upstream_component->class;
+
+       if (!upstream_component) {
+               goto error;
+       }
+
+       upstream_comp_class_type =
+               bt_component_get_class_type(upstream_component);
+       if (upstream_comp_class_type != BT_COMPONENT_CLASS_TYPE_SOURCE &&
+                       upstream_comp_class_type != BT_COMPONENT_CLASS_TYPE_FILTER) {
+               /* Unsupported operation. */
+               goto error;
+       }
+
+       iterator = bt_notification_iterator_create(upstream_component);
+       if (!iterator) {
+               goto error;
+       }
+
+       switch (upstream_comp_class_type) {
+       case BT_COMPONENT_CLASS_TYPE_SOURCE:
+       {
+               struct bt_component_class_source *source_class =
+                       container_of(upstream_comp_class,
+                               struct bt_component_class_source, parent);
+               init_method = source_class->methods.iterator.init;
+               break;
+       }
+       case BT_COMPONENT_CLASS_TYPE_FILTER:
+       {
+               struct bt_component_class_filter *filter_class =
+                       container_of(upstream_comp_class,
+                               struct bt_component_class_filter, parent);
+               init_method = filter_class->methods.iterator.init;
+               break;
+       }
+       default:
+               /* Unreachable. */
+               assert(0);
+       }
+
+       if (init_method) {
+               enum bt_notification_iterator_status status = init_method(
+                       bt_private_notification_iterator_from_notification_iterator(iterator),
+                       bt_private_port_from_port(upstream_port));
+               if (status < 0) {
+                       goto error;
+               }
+       }
+
+       ret_iterator = bt_notification_iterator_validate(iterator);
+       if (ret_iterator != BT_NOTIFICATION_ITERATOR_STATUS_OK) {
+               goto error;
+       }
+
+       goto end;
+
+error:
+       BT_PUT(iterator);
+
+end:
+       bt_put(upstream_component);
+       return iterator;
+}
diff --git a/lib/graph/filter.c b/lib/graph/filter.c
new file mode 100644 (file)
index 0000000..5931b3b
--- /dev/null
@@ -0,0 +1,259 @@
+/*
+ * filter.c
+ *
+ * Babeltrace Filter Component
+ *
+ * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/compiler-internal.h>
+#include <babeltrace/values.h>
+#include <babeltrace/graph/component-filter-internal.h>
+#include <babeltrace/graph/component-internal.h>
+#include <babeltrace/graph/component-class-internal.h>
+#include <babeltrace/graph/notification.h>
+#include <babeltrace/graph/notification-iterator-internal.h>
+
+BT_HIDDEN
+void bt_component_filter_destroy(struct bt_component *component)
+{
+}
+
+BT_HIDDEN
+struct bt_component *bt_component_filter_create(
+               struct bt_component_class *class, struct bt_value *params)
+{
+       struct bt_component_filter *filter = NULL;
+
+       filter = g_new0(struct bt_component_filter, 1);
+       if (!filter) {
+               goto end;
+       }
+
+end:
+       return filter ? &filter->parent : NULL;
+}
+
+BT_HIDDEN
+enum bt_component_status bt_component_filter_validate(
+               struct bt_component *component)
+{
+       enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
+
+       if (!component) {
+               ret = BT_COMPONENT_STATUS_INVALID;
+               goto end;
+       }
+
+       if (!component->class) {
+               ret = BT_COMPONENT_STATUS_INVALID;
+               goto end;
+       }
+
+       if (component->class->type != BT_COMPONENT_CLASS_TYPE_FILTER) {
+               ret = BT_COMPONENT_STATUS_INVALID;
+               goto end;
+       }
+
+       /* Enforce iterator limits. */
+end:
+       return ret;
+}
+
+enum bt_component_status bt_component_filter_get_input_port_count(
+               struct bt_component *component, uint64_t *count)
+{
+       enum bt_component_status status = BT_COMPONENT_STATUS_OK;
+
+       if (!component || !count ||
+                       component->class->type != BT_COMPONENT_CLASS_TYPE_FILTER) {
+               status = BT_COMPONENT_STATUS_INVALID;
+               goto end;
+       }
+
+       *count = bt_component_get_input_port_count(component);
+end:
+       return status;
+}
+
+struct bt_port *bt_component_filter_get_input_port(
+               struct bt_component *component, const char *name)
+{
+       struct bt_port *port = NULL;
+
+       if (!component || !name ||
+                       component->class->type != BT_COMPONENT_CLASS_TYPE_FILTER) {
+               goto end;
+       }
+
+       port = bt_component_get_input_port(component, name);
+end:
+       return port;
+}
+
+struct bt_port *bt_component_filter_get_input_port_at_index(
+               struct bt_component *component, int index)
+{
+       struct bt_port *port = NULL;
+
+       if (!component ||
+                       component->class->type != BT_COMPONENT_CLASS_TYPE_FILTER) {
+               goto end;
+       }
+
+       port = bt_component_get_input_port_at_index(component, index);
+end:
+       return port;
+}
+
+struct bt_port *bt_component_filter_get_default_input_port(
+               struct bt_component *component)
+{
+       return bt_component_filter_get_input_port(component,
+                       DEFAULT_INPUT_PORT_NAME);
+}
+
+enum bt_component_status bt_component_filter_get_output_port_count(
+               struct bt_component *component, uint64_t *count)
+{
+       enum bt_component_status status = BT_COMPONENT_STATUS_OK;
+
+       if (!component || !count ||
+                       component->class->type != BT_COMPONENT_CLASS_TYPE_FILTER) {
+               status = BT_COMPONENT_STATUS_INVALID;
+               goto end;
+       }
+
+       *count = bt_component_get_output_port_count(component);
+end:
+       return status;
+}
+
+struct bt_port *bt_component_filter_get_output_port(
+               struct bt_component *component, const char *name)
+{
+       struct bt_port *port = NULL;
+
+       if (!component || !name ||
+                       component->class->type != BT_COMPONENT_CLASS_TYPE_FILTER) {
+               goto end;
+       }
+
+       port = bt_component_get_output_port(component, name);
+end:
+       return port;
+}
+
+struct bt_port *bt_component_filter_get_output_port_at_index(
+               struct bt_component *component, int index)
+{
+       struct bt_port *port = NULL;
+
+       if (!component ||
+                       component->class->type != BT_COMPONENT_CLASS_TYPE_FILTER) {
+               goto end;
+       }
+
+       port = bt_component_get_output_port_at_index(component, index);
+end:
+       return port;
+}
+
+struct bt_port *bt_component_filter_get_default_output_port(
+               struct bt_component *component)
+{
+       return bt_component_filter_get_output_port(component,
+                       DEFAULT_OUTPUT_PORT_NAME);
+}
+
+struct bt_private_port *
+bt_private_component_filter_get_input_private_port_at_index(
+               struct bt_private_component *private_component, int index)
+{
+       return bt_private_port_from_port(
+               bt_component_filter_get_input_port_at_index(
+                       bt_component_from_private(private_component), index));
+}
+
+struct bt_private_port *
+bt_private_component_filter_get_default_input_private_port(
+               struct bt_private_component *private_component)
+{
+       return bt_private_port_from_port(
+               bt_component_filter_get_default_input_port(
+                       bt_component_from_private(private_component)));
+}
+
+struct bt_private_port *bt_private_component_filter_add_input_private_port(
+               struct bt_private_component *private_component,
+               const char *name)
+{
+       struct bt_port *port = NULL;
+       struct bt_component *component =
+               bt_component_from_private(private_component);
+
+       if (!component ||
+                       component->class->type != BT_COMPONENT_CLASS_TYPE_FILTER) {
+               goto end;
+       }
+
+       port = bt_component_add_input_port(component, name);
+end:
+       return bt_private_port_from_port(port);
+}
+
+struct bt_private_port *
+bt_private_component_filter_get_output_private_port_at_index(
+               struct bt_private_component *private_component, int index)
+{
+       return bt_private_port_from_port(
+               bt_component_filter_get_output_port_at_index(
+                       bt_component_from_private(private_component), index));
+}
+
+struct bt_private_port *
+bt_private_component_filter_get_default_output_private_port(
+               struct bt_private_component *private_component)
+{
+       return bt_private_port_from_port(
+               bt_component_filter_get_default_output_port(
+                       bt_component_from_private(private_component)));
+}
+
+struct bt_private_port *bt_private_component_filter_add_output_private_port(
+               struct bt_private_component *private_component,
+               const char *name)
+{
+       struct bt_port *port = NULL;
+       struct bt_component *component =
+               bt_component_from_private(private_component);
+
+       if (!component ||
+                       component->class->type != BT_COMPONENT_CLASS_TYPE_FILTER) {
+               goto end;
+       }
+
+       port = bt_component_add_output_port(component, name);
+end:
+       return bt_private_port_from_port(port);
+}
diff --git a/lib/graph/graph.c b/lib/graph/graph.c
new file mode 100644 (file)
index 0000000..c861fa3
--- /dev/null
@@ -0,0 +1,777 @@
+/*
+ * graph.c
+ *
+ * Babeltrace Plugin Component Graph
+ *
+ * Copyright 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/graph/component-internal.h>
+#include <babeltrace/graph/graph-internal.h>
+#include <babeltrace/graph/connection-internal.h>
+#include <babeltrace/graph/component-sink-internal.h>
+#include <babeltrace/graph/component-source.h>
+#include <babeltrace/graph/component-filter.h>
+#include <babeltrace/graph/port.h>
+#include <babeltrace/compiler-internal.h>
+#include <unistd.h>
+#include <glib.h>
+
+struct bt_graph_listener {
+       void *func;
+       void *data;
+};
+
+static
+void bt_graph_destroy(struct bt_object *obj)
+{
+       struct bt_graph *graph = container_of(obj,
+                       struct bt_graph, base);
+
+       if (graph->components) {
+               g_ptr_array_free(graph->components, TRUE);
+       }
+       if (graph->connections) {
+               g_ptr_array_free(graph->connections, TRUE);
+       }
+       if (graph->sinks_to_consume) {
+               g_queue_free(graph->sinks_to_consume);
+       }
+
+       if (graph->listeners.port_added) {
+               g_array_free(graph->listeners.port_added, TRUE);
+       }
+
+       if (graph->listeners.port_removed) {
+               g_array_free(graph->listeners.port_removed, TRUE);
+       }
+
+       if (graph->listeners.ports_connected) {
+               g_array_free(graph->listeners.ports_connected, TRUE);
+       }
+
+       if (graph->listeners.ports_disconnected) {
+               g_array_free(graph->listeners.ports_disconnected, TRUE);
+       }
+
+       g_free(graph);
+}
+
+static
+int init_listeners_array(GArray **listeners)
+{
+       int ret = 0;
+
+       assert(listeners);
+       *listeners = g_array_new(FALSE, TRUE, sizeof(struct bt_graph_listener));
+       if (!*listeners) {
+               ret = -1;
+               goto end;
+       }
+
+end:
+       return ret;
+}
+
+struct bt_graph *bt_graph_create(void)
+{
+       struct bt_graph *graph;
+       int ret;
+
+       graph = g_new0(struct bt_graph, 1);
+       if (!graph) {
+               goto end;
+       }
+
+       bt_object_init(graph, bt_graph_destroy);
+
+       graph->connections = g_ptr_array_new_with_free_func(bt_object_release);
+       if (!graph->connections) {
+               goto error;
+       }
+       graph->components = g_ptr_array_new_with_free_func(bt_object_release);
+       if (!graph->components) {
+               goto error;
+       }
+       graph->sinks_to_consume = g_queue_new();
+       if (!graph->sinks_to_consume) {
+               goto error;
+       }
+
+       ret = init_listeners_array(&graph->listeners.port_added);
+       if (ret) {
+               goto error;
+       }
+
+       ret = init_listeners_array(&graph->listeners.port_removed);
+       if (ret) {
+               goto error;
+       }
+
+       ret = init_listeners_array(&graph->listeners.ports_connected);
+       if (ret) {
+               goto error;
+       }
+
+       ret = init_listeners_array(&graph->listeners.ports_disconnected);
+       if (ret) {
+               goto error;
+       }
+
+end:
+       return graph;
+error:
+       BT_PUT(graph);
+       goto end;
+}
+
+struct bt_connection *bt_graph_connect_ports(struct bt_graph *graph,
+               struct bt_port *upstream_port,
+               struct bt_port *downstream_port)
+{
+       struct bt_connection *connection = NULL;
+       struct bt_graph *upstream_graph = NULL;
+       struct bt_graph *downstream_graph = NULL;
+       struct bt_component *upstream_component = NULL;
+       struct bt_component *downstream_component = NULL;
+       struct bt_connection *existing_conn = NULL;
+       enum bt_component_status component_status;
+       bool upstream_was_already_in_graph;
+       bool downstream_was_already_in_graph;
+       int components_to_remove = 0;
+       int i;
+
+       if (!graph || !upstream_port || !downstream_port) {
+               goto end;
+       }
+
+       /* Ensure appropriate types for upstream and downstream ports. */
+       if (bt_port_get_type(upstream_port) != BT_PORT_TYPE_OUTPUT) {
+               goto end;
+       }
+       if (bt_port_get_type(downstream_port) != BT_PORT_TYPE_INPUT) {
+               goto end;
+       }
+
+       /* Ensure that both ports are currently unconnected. */
+       existing_conn = bt_port_get_connection(upstream_port);
+       bt_put(existing_conn);
+       if (existing_conn) {
+               fprintf(stderr, "Upstream port is already connected\n");
+               goto end;
+       }
+
+       existing_conn = bt_port_get_connection(downstream_port);
+       bt_put(existing_conn);
+       if (existing_conn) {
+               fprintf(stderr, "Downstream port is already connected\n");
+               goto end;
+       }
+
+       /*
+        * Ensure that both ports are still attached to their creating
+        * component.
+        */
+       upstream_component = bt_port_get_component(upstream_port);
+       if (!upstream_component) {
+               fprintf(stderr, "Upstream port does not belong to a component\n");
+               goto end;
+       }
+
+       downstream_component = bt_port_get_component(downstream_port);
+       if (!downstream_component) {
+               fprintf(stderr, "Downstream port does not belong to a component\n");
+               goto end;
+       }
+
+       /* Ensure the components are not already part of another graph. */
+       upstream_graph = bt_component_get_graph(upstream_component);
+       if (upstream_graph && (graph != upstream_graph)) {
+               fprintf(stderr, "Upstream component is already part of another graph\n");
+               goto error;
+       }
+       upstream_was_already_in_graph = (graph == upstream_graph);
+       downstream_graph = bt_component_get_graph(downstream_component);
+       if (downstream_graph && (graph != downstream_graph)) {
+               fprintf(stderr, "Downstream component is already part of another graph\n");
+               goto error;
+       }
+       downstream_was_already_in_graph = (graph == downstream_graph);
+
+       connection = bt_connection_create(graph, upstream_port,
+                       downstream_port);
+       if (!connection) {
+               goto error;
+       }
+
+       /*
+        * Ownership of upstream_component/downstream_component and of
+        * the connection object is transferred to the graph.
+        */
+       g_ptr_array_add(graph->connections, connection);
+
+       if (!upstream_was_already_in_graph) {
+               g_ptr_array_add(graph->components, upstream_component);
+               bt_component_set_graph(upstream_component, graph);
+       }
+       if (!downstream_was_already_in_graph) {
+               g_ptr_array_add(graph->components, downstream_component);
+               bt_component_set_graph(downstream_component, graph);
+               if (bt_component_get_class_type(downstream_component) ==
+                               BT_COMPONENT_CLASS_TYPE_SINK) {
+                       g_queue_push_tail(graph->sinks_to_consume,
+                                       downstream_component);
+               }
+       }
+
+       /*
+        * The graph is now the parent of these components which garantees their
+        * existence for the duration of the graph's lifetime.
+        */
+
+       /*
+        * The components and connection are added to the graph before
+        * invoking the `accept_port_connection` method in order to make
+        * them visible to the components during the method's
+        * invocation.
+        */
+       component_status = bt_component_accept_port_connection(
+               upstream_component, upstream_port, downstream_port);
+       if (component_status != BT_COMPONENT_STATUS_OK) {
+               goto error_rollback;
+       }
+       component_status = bt_component_accept_port_connection(
+               downstream_component, downstream_port, upstream_port);
+       if (component_status != BT_COMPONENT_STATUS_OK) {
+               goto error_rollback;
+       }
+
+       /*
+        * Both components accepted the connection. Notify the graph's
+        * creator that both ports are connected.
+        */
+       bt_graph_notify_ports_connected(graph, upstream_port, downstream_port);
+
+end:
+       bt_put(upstream_graph);
+       bt_put(downstream_graph);
+       bt_put(upstream_component);
+       bt_put(downstream_component);
+       return connection;
+error_rollback:
+       /*
+        * Remove newly-added components from the graph, being careful
+        * not to remove a component that was already present in the graph
+        * and is connected to other components.
+        */
+       components_to_remove += upstream_was_already_in_graph ? 0 : 1;
+       components_to_remove += downstream_was_already_in_graph ? 0 : 1;
+
+       if (!downstream_was_already_in_graph) {
+               if (bt_component_get_class_type(downstream_component) ==
+                               BT_COMPONENT_CLASS_TYPE_SINK) {
+                       g_queue_pop_tail(graph->sinks_to_consume);
+               }
+       }
+       /* Remove newly created connection. */
+       g_ptr_array_set_size(graph->connections,
+                       graph->connections->len - 1);
+
+       /*
+        * Remove newly added components.
+        *
+        * Note that this is a tricky situation. The graph, being the parent
+        * of the components, does not hold a reference to them. Normally,
+        * components are destroyed right away when the graph is released since
+        * the graph, being their parent, bounds their lifetime
+        * (see doc/ref-counting.md).
+        *
+        * In this particular case, we must take a number of steps:
+        *   1) unset the components' parent to rollback the initial state of
+        *      the components being connected.
+        *      Note that the reference taken by the component on its graph is
+        *      released by the set_parent call.
+        *   2) set the pointer in the components array to NULL so that the
+        *      destruction function called on the array's resize in invoked on
+        *      NULL (no effect),
+        *
+        * NOTE: Point #1 assumes that *something* holds a reference to both
+        *       components being connected. The fact that a reference is being
+        *       held to a component means that it must hold a reference to its
+        *       parent to prevent the parent from being destroyed (again, refer
+        *       to doc/red-counting.md). This reference to a component is
+        *       most likely being held *transitively* by the caller which holds
+        *       a reference to both ports (a port has its component as a
+        *       parent).
+        *
+        *       This assumes that a graph is not connecting components by
+        *       itself while not holding a reference to the ports/components
+        *       being connected (i.e. "cheating" by using internal APIs).
+        */
+       for (i = 0; i < components_to_remove; i++) {
+               struct bt_component *component = g_ptr_array_index(
+                               graph->components, graph->components->len - 1);
+
+               bt_component_set_graph(component, NULL);
+               g_ptr_array_index(graph->components,
+                               graph->components->len - 1) = NULL;
+               g_ptr_array_set_size(graph->components,
+                               graph->components->len - 1);
+       }
+       /* NOTE: Resizing the ptr_arrays invokes the destruction of the elements. */
+       goto end;
+error:
+       BT_PUT(upstream_component);
+       BT_PUT(downstream_component);
+       goto end;
+}
+
+static
+enum bt_component_status get_component_port_counts(
+               struct bt_component *component, uint64_t *input_count,
+               uint64_t *output_count)
+{
+       enum bt_component_status ret;
+
+       switch (bt_component_get_class_type(component)) {
+       case BT_COMPONENT_CLASS_TYPE_SOURCE:
+               ret = bt_component_source_get_output_port_count(component,
+                               output_count);
+               if (ret != BT_COMPONENT_STATUS_OK) {
+                       goto end;
+               }
+               break;
+       case BT_COMPONENT_CLASS_TYPE_FILTER:
+               ret = bt_component_filter_get_output_port_count(component,
+                               output_count);
+               if (ret != BT_COMPONENT_STATUS_OK) {
+                       goto end;
+               }
+               ret = bt_component_filter_get_input_port_count(component,
+                               input_count);
+               if (ret != BT_COMPONENT_STATUS_OK) {
+                       goto end;
+               }
+               break;
+       case BT_COMPONENT_CLASS_TYPE_SINK:
+               ret = bt_component_sink_get_input_port_count(component,
+                               input_count);
+               if (ret != BT_COMPONENT_STATUS_OK) {
+                       goto end;
+               }
+               break;
+       default:
+               assert(false);
+               break;
+       }
+       ret = BT_COMPONENT_STATUS_OK;
+end:
+       return ret;
+}
+
+enum bt_graph_status bt_graph_add_component_as_sibling(struct bt_graph *graph,
+               struct bt_component *origin,
+               struct bt_component *new_component)
+{
+       uint64_t origin_input_port_count = 0;
+       uint64_t origin_output_port_count = 0;
+       uint64_t new_input_port_count = 0;
+       uint64_t new_output_port_count = 0;
+       enum bt_graph_status status = BT_GRAPH_STATUS_OK;
+       struct bt_graph *origin_graph = NULL;
+       struct bt_graph *new_graph = NULL;
+       struct bt_port *origin_port = NULL;
+       struct bt_port *new_port = NULL;
+       struct bt_port *upstream_port = NULL;
+       struct bt_port *downstream_port = NULL;
+       struct bt_connection *origin_connection = NULL;
+       struct bt_connection *new_connection = NULL;
+        int port_index;
+
+       if (!graph || !origin || !new_component) {
+               status = BT_GRAPH_STATUS_INVALID;
+               goto end;
+       }
+
+       if (bt_component_get_class_type(origin) !=
+                       bt_component_get_class_type(new_component)) {
+               status = BT_GRAPH_STATUS_INVALID;
+               goto end;
+       }
+
+        origin_graph = bt_component_get_graph(origin);
+       if (!origin_graph || (origin_graph != graph)) {
+               status = BT_GRAPH_STATUS_INVALID;
+               goto end;
+       }
+
+        new_graph = bt_component_get_graph(new_component);
+       if (new_graph) {
+               status = BT_GRAPH_STATUS_ALREADY_IN_A_GRAPH;
+               goto end;
+       }
+
+       if (get_component_port_counts(origin, &origin_input_port_count,
+                       &origin_output_port_count) != BT_COMPONENT_STATUS_OK) {
+               status = BT_GRAPH_STATUS_INVALID;
+               goto end;
+       }
+       if (get_component_port_counts(new_component, &new_input_port_count,
+                       &new_output_port_count) != BT_COMPONENT_STATUS_OK) {
+               status = BT_GRAPH_STATUS_INVALID;
+               goto end;
+       }
+
+       if (origin_input_port_count != new_input_port_count ||
+                       origin_output_port_count != new_output_port_count) {
+               status = BT_GRAPH_STATUS_INVALID;
+               goto end;
+       }
+
+       /* Replicate input connections. */
+       for (port_index = 0; port_index< origin_input_port_count; port_index++) {
+               origin_port = bt_component_get_input_port_at_index(origin,
+                       port_index);
+               if (!origin_port) {
+                       status = BT_GRAPH_STATUS_ERROR;
+                       goto error_disconnect;
+               }
+
+               new_port = bt_component_get_input_port_at_index(new_component,
+                       port_index);
+               if (!new_port) {
+                       status = BT_GRAPH_STATUS_ERROR;
+                       goto error_disconnect;
+               }
+
+               origin_connection = bt_port_get_connection(origin_port);
+               if (origin_connection) {
+                       upstream_port = bt_connection_get_upstream_port(
+                               origin_connection);
+                       if (!upstream_port) {
+                               goto error_disconnect;
+                       }
+
+                       new_connection = bt_graph_connect_ports(graph,
+                               upstream_port, new_port);
+                       if (!new_connection) {
+                               goto error_disconnect;
+                       }
+               }
+
+               BT_PUT(upstream_port);
+               BT_PUT(origin_connection);
+               BT_PUT(new_connection);
+               BT_PUT(origin_port);
+               BT_PUT(new_port);
+       }
+
+       /* Replicate output connections. */
+       for (port_index = 0; port_index < origin_output_port_count; port_index++) {
+               origin_port = bt_component_get_output_port_at_index(origin,
+                       port_index);
+               if (!origin_port) {
+                       status = BT_GRAPH_STATUS_ERROR;
+                       goto error_disconnect;
+               }
+               new_port = bt_component_get_output_port_at_index(new_component,
+                       port_index);
+               if (!new_port) {
+                       status = BT_GRAPH_STATUS_ERROR;
+                       goto error_disconnect;
+               }
+
+               origin_connection = bt_port_get_connection(origin_port);
+               if (origin_connection) {
+                       downstream_port = bt_connection_get_downstream_port(
+                                       origin_connection);
+                       if (!downstream_port) {
+                               goto error_disconnect;
+                       }
+
+                       new_connection = bt_graph_connect_ports(graph,
+                               new_port, downstream_port);
+                       if (!new_connection) {
+                               goto error_disconnect;
+                       }
+               }
+
+               BT_PUT(downstream_port);
+               BT_PUT(origin_connection);
+               BT_PUT(new_connection);
+               BT_PUT(origin_port);
+               BT_PUT(new_port);
+       }
+end:
+       bt_put(origin_graph);
+       bt_put(new_graph);
+       bt_put(origin_port);
+       bt_put(new_port);
+       bt_put(upstream_port);
+       bt_put(downstream_port);
+       bt_put(origin_connection);
+       bt_put(new_connection);
+       return status;
+error_disconnect:
+       /* Destroy all connections of the new component. */
+       /* FIXME. */
+       goto end;
+}
+
+enum bt_graph_status bt_graph_consume(struct bt_graph *graph)
+{
+       struct bt_component *sink;
+       enum bt_graph_status status = BT_GRAPH_STATUS_OK;
+       enum bt_component_status comp_status;
+       GList *current_node;
+
+       if (!graph) {
+               status = BT_GRAPH_STATUS_INVALID;
+               goto end;
+       }
+
+       if (g_queue_is_empty(graph->sinks_to_consume)) {
+               status = BT_GRAPH_STATUS_END;
+               goto end;
+       }
+
+       current_node = g_queue_pop_head_link(graph->sinks_to_consume);
+       sink = current_node->data;
+       comp_status = bt_component_sink_consume(sink);
+       switch (comp_status) {
+       case BT_COMPONENT_STATUS_OK:
+               break;
+       case BT_COMPONENT_STATUS_END:
+               status = BT_GRAPH_STATUS_END;
+               break;
+       case BT_COMPONENT_STATUS_AGAIN:
+               status = BT_GRAPH_STATUS_AGAIN;
+               break;
+       case BT_COMPONENT_STATUS_INVALID:
+               status = BT_GRAPH_STATUS_INVALID;
+               break;
+       default:
+               status = BT_GRAPH_STATUS_ERROR;
+               break;
+       }
+
+       if (status != BT_GRAPH_STATUS_END) {
+               g_queue_push_tail_link(graph->sinks_to_consume, current_node);
+               goto end;
+       }
+
+       /* End reached, the node is not added back to the queue and free'd. */
+       g_queue_delete_link(graph->sinks_to_consume, current_node);
+
+       /* Don't forward an END status if there are sinks left to consume. */
+       if (!g_queue_is_empty(graph->sinks_to_consume)) {
+               status = BT_GRAPH_STATUS_OK;
+               goto end;
+       }
+end:
+       return status;
+}
+
+enum bt_graph_status bt_graph_run(struct bt_graph *graph)
+{
+       enum bt_graph_status status = BT_GRAPH_STATUS_OK;
+
+       if (!graph) {
+               status = BT_GRAPH_STATUS_INVALID;
+               goto error;
+       }
+
+       do {
+               status = bt_graph_consume(graph);
+               if (status == BT_GRAPH_STATUS_AGAIN) {
+                       /*
+                        * If AGAIN is received and there are multiple sinks,
+                        * go ahead and consume from the next sink.
+                        *
+                        * However, in the case where a single sink is left,
+                        * the caller can decide to busy-wait and call
+                        * bt_graph_run continuously until the source is ready
+                        * or it can decide to sleep for an arbitrary amount of
+                        * time.
+                        */
+                       if (graph->sinks_to_consume->length > 1) {
+                               status = BT_GRAPH_STATUS_OK;
+                       }
+               }
+       } while (status == BT_GRAPH_STATUS_OK);
+
+       if (g_queue_is_empty(graph->sinks_to_consume)) {
+               status = BT_GRAPH_STATUS_END;
+       }
+error:
+       return status;
+}
+
+static
+void add_listener(GArray *listeners, void *func, void *data)
+{
+       struct bt_graph_listener listener = {
+               .func = func,
+               .data = data,
+       };
+
+       g_array_append_val(listeners, listener);
+}
+
+enum bt_graph_status bt_graph_add_port_added_listener(
+               struct bt_graph *graph,
+               bt_graph_port_added_listener listener, void *data)
+{
+       enum bt_graph_status status = BT_GRAPH_STATUS_OK;
+
+       if (!graph || !listener) {
+               status = BT_GRAPH_STATUS_INVALID;
+               goto end;
+       }
+
+       add_listener(graph->listeners.port_added, listener, data);
+
+end:
+       return status;
+}
+
+enum bt_graph_status bt_graph_add_port_removed_listener(
+               struct bt_graph *graph,
+               bt_graph_port_removed_listener listener, void *data)
+{
+       enum bt_graph_status status = BT_GRAPH_STATUS_OK;
+
+       if (!graph || !listener) {
+               status = BT_GRAPH_STATUS_INVALID;
+               goto end;
+       }
+
+       add_listener(graph->listeners.port_removed, listener, data);
+
+end:
+       return status;
+}
+
+enum bt_graph_status bt_graph_add_ports_connected_listener(
+               struct bt_graph *graph,
+               bt_graph_ports_connected_listener listener, void *data)
+{
+       enum bt_graph_status status = BT_GRAPH_STATUS_OK;
+
+       if (!graph || !listener) {
+               status = BT_GRAPH_STATUS_INVALID;
+               goto end;
+       }
+
+       add_listener(graph->listeners.ports_connected, listener, data);
+
+end:
+       return status;
+}
+
+enum bt_graph_status bt_graph_add_ports_disconnected_listener(
+               struct bt_graph *graph,
+               bt_graph_ports_disconnected_listener listener, void *data)
+{
+       enum bt_graph_status status = BT_GRAPH_STATUS_OK;
+
+       if (!graph || !listener) {
+               status = BT_GRAPH_STATUS_INVALID;
+               goto end;
+       }
+
+       add_listener(graph->listeners.ports_disconnected, listener, data);
+
+end:
+       return status;
+}
+
+BT_HIDDEN
+void bt_graph_notify_port_added(struct bt_graph *graph, struct bt_port *port)
+{
+       size_t i;
+
+       for (i = 0; i < graph->listeners.port_added->len; i++) {
+               struct bt_graph_listener listener =
+                       g_array_index(graph->listeners.port_added,
+                               struct bt_graph_listener, i);
+               bt_graph_port_added_listener func = listener.func;
+
+               assert(func);
+               func(port, listener.data);
+       }
+}
+
+BT_HIDDEN
+void bt_graph_notify_port_removed(struct bt_graph *graph,
+               struct bt_component *comp, struct bt_port *port)
+{
+       size_t i;
+
+       for (i = 0; i < graph->listeners.port_removed->len; i++) {
+               struct bt_graph_listener listener =
+                       g_array_index(graph->listeners.port_removed,
+                               struct bt_graph_listener, i);
+               bt_graph_port_removed_listener func = listener.func;
+
+               assert(func);
+               func(comp, port, listener.data);
+       }
+}
+
+BT_HIDDEN
+void bt_graph_notify_ports_connected(struct bt_graph *graph,
+               struct bt_port *upstream_port, struct bt_port *downstream_port)
+{
+       size_t i;
+
+       for (i = 0; i < graph->listeners.ports_connected->len; i++) {
+               struct bt_graph_listener listener =
+                       g_array_index(graph->listeners.ports_connected,
+                               struct bt_graph_listener, i);
+               bt_graph_ports_connected_listener func = listener.func;
+
+               assert(func);
+               func(upstream_port, downstream_port, listener.data);
+       }
+}
+
+BT_HIDDEN
+void bt_graph_notify_ports_disconnected(struct bt_graph *graph,
+               struct bt_component *upstream_comp,
+               struct bt_component *downstream_comp,
+               struct bt_port *upstream_port, struct bt_port *downstream_port)
+{
+       size_t i;
+
+       for (i = 0; i < graph->listeners.ports_disconnected->len; i++) {
+               struct bt_graph_listener listener =
+                       g_array_index(graph->listeners.ports_disconnected,
+                               struct bt_graph_listener, i);
+               bt_graph_ports_disconnected_listener func = listener.func;
+
+               assert(func);
+               func(upstream_comp, downstream_comp, upstream_port,
+                       downstream_port, listener.data);
+       }
+}
diff --git a/lib/graph/iterator.c b/lib/graph/iterator.c
new file mode 100644 (file)
index 0000000..2956295
--- /dev/null
@@ -0,0 +1,260 @@
+/*
+ * iterator.c
+ *
+ * Babeltrace Notification Iterator
+ *
+ * Copyright 2015 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/compiler-internal.h>
+#include <babeltrace/ref.h>
+#include <babeltrace/graph/component.h>
+#include <babeltrace/graph/component-source-internal.h>
+#include <babeltrace/graph/component-class-internal.h>
+#include <babeltrace/graph/notification-iterator.h>
+#include <babeltrace/graph/notification-iterator-internal.h>
+#include <babeltrace/graph/notification-internal.h>
+
+static
+void bt_notification_iterator_destroy(struct bt_object *obj)
+{
+       struct bt_notification_iterator *iterator;
+       struct bt_component_class *comp_class;
+
+       assert(obj);
+       iterator = container_of(obj, struct bt_notification_iterator,
+                       base);
+       assert(iterator->component);
+       comp_class = iterator->component->class;
+
+       /* Call user-defined destroy method */
+       switch (comp_class->type) {
+       case BT_COMPONENT_CLASS_TYPE_SOURCE:
+       {
+               struct bt_component_class_source *source_class;
+
+               source_class = container_of(comp_class, struct bt_component_class_source, parent);
+
+               if (source_class->methods.iterator.finalize) {
+                       source_class->methods.iterator.finalize(
+                               bt_private_notification_iterator_from_notification_iterator(iterator));
+               }
+               break;
+       }
+       case BT_COMPONENT_CLASS_TYPE_FILTER:
+       {
+               struct bt_component_class_filter *filter_class;
+
+               filter_class = container_of(comp_class, struct bt_component_class_filter, parent);
+
+               if (filter_class->methods.iterator.finalize) {
+                       filter_class->methods.iterator.finalize(
+                               bt_private_notification_iterator_from_notification_iterator(iterator));
+               }
+               break;
+       }
+       default:
+               /* Unreachable */
+               assert(0);
+       }
+
+       BT_PUT(iterator->current_notification);
+       BT_PUT(iterator->component);
+       g_free(iterator);
+}
+
+BT_HIDDEN
+struct bt_notification_iterator *bt_notification_iterator_create(
+               struct bt_component *component)
+{
+       enum bt_component_class_type type;
+       struct bt_notification_iterator *iterator = NULL;
+
+       if (!component) {
+               goto end;
+       }
+
+       type = bt_component_get_class_type(component);
+       switch (type) {
+       case BT_COMPONENT_CLASS_TYPE_SOURCE:
+       case BT_COMPONENT_CLASS_TYPE_FILTER:
+               break;
+       default:
+               goto end;
+       }
+
+       iterator = g_new0(struct bt_notification_iterator, 1);
+       if (!iterator) {
+               goto end;
+       }
+
+       iterator->component = bt_get(component);
+       bt_object_init(iterator, bt_notification_iterator_destroy);
+end:
+       return iterator;
+}
+
+BT_HIDDEN
+enum bt_notification_iterator_status bt_notification_iterator_validate(
+               struct bt_notification_iterator *iterator)
+{
+       enum bt_notification_iterator_status ret =
+                       BT_NOTIFICATION_ITERATOR_STATUS_OK;
+
+       if (!iterator) {
+               ret = BT_NOTIFICATION_ITERATOR_STATUS_INVAL;
+               goto end;
+       }
+end:
+       return ret;
+}
+
+void *bt_private_notification_iterator_get_user_data(
+               struct bt_private_notification_iterator *private_iterator)
+{
+       struct bt_notification_iterator *iterator =
+               bt_notification_iterator_from_private(private_iterator);
+
+       return iterator ? iterator->user_data : NULL;
+}
+
+enum bt_notification_iterator_status
+bt_private_notification_iterator_set_user_data(
+               struct bt_private_notification_iterator *private_iterator,
+               void *data)
+{
+       enum bt_notification_iterator_status ret =
+                       BT_NOTIFICATION_ITERATOR_STATUS_OK;
+       struct bt_notification_iterator *iterator =
+               bt_notification_iterator_from_private(private_iterator);
+
+       if (!iterator) {
+               ret = BT_NOTIFICATION_ITERATOR_STATUS_INVAL;
+               goto end;
+       }
+
+       iterator->user_data = data;
+end:
+       return ret;
+}
+
+struct bt_notification *bt_notification_iterator_get_notification(
+               struct bt_notification_iterator *iterator)
+{
+       struct bt_notification *notification = NULL;
+
+       if (!iterator) {
+               goto end;
+       }
+
+       notification = bt_get(iterator->current_notification);
+
+end:
+       return notification;
+}
+
+enum bt_notification_iterator_status
+bt_notification_iterator_next(struct bt_notification_iterator *iterator)
+{
+       struct bt_private_notification_iterator *priv_iterator =
+               bt_private_notification_iterator_from_notification_iterator(iterator);
+       bt_component_class_notification_iterator_next_method next_method = NULL;
+       struct bt_notification_iterator_next_return next_return;
+       enum bt_notification_iterator_status status =
+               BT_NOTIFICATION_ITERATOR_STATUS_OK;
+
+       if (!iterator) {
+               status = BT_NOTIFICATION_ITERATOR_STATUS_INVAL;
+               goto end;
+       }
+
+       assert(iterator->component);
+       assert(iterator->component->class);
+
+       switch (iterator->component->class->type) {
+       case BT_COMPONENT_CLASS_TYPE_SOURCE:
+       {
+               struct bt_component_class_source *source_class =
+                       container_of(iterator->component->class,
+                               struct bt_component_class_source, parent);
+
+               assert(source_class->methods.iterator.next);
+               next_method = source_class->methods.iterator.next;
+               break;
+       }
+       case BT_COMPONENT_CLASS_TYPE_FILTER:
+       {
+               struct bt_component_class_filter *filter_class =
+                       container_of(iterator->component->class,
+                               struct bt_component_class_filter, parent);
+
+               assert(filter_class->methods.iterator.next);
+               next_method = filter_class->methods.iterator.next;
+               break;
+       }
+       default:
+               assert(false);
+               break;
+       }
+
+       assert(next_method);
+       next_return = next_method(priv_iterator);
+       if (next_return.status == BT_NOTIFICATION_ITERATOR_STATUS_OK) {
+               if (!next_return.notification) {
+                       status = BT_NOTIFICATION_ITERATOR_STATUS_ERROR;
+                       goto end;
+               }
+
+               BT_MOVE(iterator->current_notification,
+                       next_return.notification);
+               bt_notification_freeze(iterator->current_notification);
+       }
+
+end:
+       return next_return.status;
+}
+
+struct bt_component *bt_notification_iterator_get_component(
+               struct bt_notification_iterator *iterator)
+{
+       return bt_get(iterator->component);
+}
+
+struct bt_private_component *
+bt_private_notification_iterator_get_private_component(
+               struct bt_private_notification_iterator *private_iterator)
+{
+       return bt_private_component_from_component(
+               bt_notification_iterator_get_component(
+                       bt_notification_iterator_from_private(private_iterator)));
+}
+
+enum bt_notification_iterator_status bt_notification_iterator_seek_time(
+               struct bt_notification_iterator *iterator,
+               enum bt_notification_iterator_seek_origin seek_origin,
+               int64_t time)
+{
+       enum bt_notification_iterator_status ret =
+                       BT_NOTIFICATION_ITERATOR_STATUS_UNSUPPORTED;
+       return ret;
+}
diff --git a/lib/graph/notification/Makefile.am b/lib/graph/notification/Makefile.am
new file mode 100644 (file)
index 0000000..db32a43
--- /dev/null
@@ -0,0 +1,11 @@
+AM_CFLAGS = $(PACKAGE_CFLAGS) -I$(top_srcdir)/include
+
+noinst_LTLIBRARIES = libgraph-notification.la
+
+libgraph_notification_la_SOURCES = \
+       notification.c \
+       packet.c \
+       event.c \
+       stream.c \
+       heap.c \
+       inactivity.c
diff --git a/lib/graph/notification/event.c b/lib/graph/notification/event.c
new file mode 100644 (file)
index 0000000..a9fbf48
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * Babeltrace Plug-in Event Notification
+ *
+ * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/compiler-internal.h>
+#include <babeltrace/ctf-ir/event.h>
+#include <babeltrace/ctf-ir/event-internal.h>
+#include <babeltrace/ctf-ir/event-class.h>
+#include <babeltrace/ctf-ir/stream-class.h>
+#include <babeltrace/ctf-ir/trace.h>
+#include <babeltrace/graph/clock-class-priority-map.h>
+#include <babeltrace/graph/notification-event-internal.h>
+
+static
+void bt_notification_event_destroy(struct bt_object *obj)
+{
+       struct bt_notification_event *notification =
+                       (struct bt_notification_event *) obj;
+
+       BT_PUT(notification->event);
+       BT_PUT(notification->cc_prio_map);
+       g_free(notification);
+}
+
+static
+bool validate_clock_classes(struct bt_notification_event *notif)
+{
+       /*
+        * For each clock class found in the event's trace, get the
+        * event's clock value for this clock class, and if it exists,
+        * make sure that this clock class has a priority in the
+        * notification's clock class priority map.
+        */
+       bool is_valid = true;
+       int ret;
+       int count;
+       size_t i;
+       struct bt_ctf_event_class *event_class = NULL;
+       struct bt_ctf_stream_class *stream_class = NULL;
+       struct bt_ctf_trace *trace = NULL;
+       uint64_t prio;
+
+       event_class = bt_ctf_event_get_class(notif->event);
+       assert(event_class);
+       stream_class = bt_ctf_event_class_get_stream_class(event_class);
+       assert(stream_class);
+       trace = bt_ctf_stream_class_get_trace(stream_class);
+       assert(trace);
+       count = bt_ctf_trace_get_clock_class_count(trace);
+       assert(count >= 0);
+
+       for (i = 0; i < count; i++) {
+               struct bt_ctf_clock_class *clock_class =
+                       bt_ctf_trace_get_clock_class(trace, i);
+
+               assert(clock_class);
+               ret = bt_clock_class_priority_map_get_clock_class_priority(
+                       notif->cc_prio_map, clock_class, &prio);
+               bt_put(clock_class);
+               if (ret) {
+                       is_valid = false;
+                       goto end;
+               }
+       }
+
+end:
+       bt_put(trace);
+       bt_put(stream_class);
+       bt_put(event_class);
+       return is_valid;
+}
+
+struct bt_notification *bt_notification_event_create(struct bt_ctf_event *event,
+               struct bt_clock_class_priority_map *cc_prio_map)
+{
+       struct bt_notification_event *notification = NULL;
+
+       if (!event || !cc_prio_map) {
+               goto error;
+       }
+
+       if (!bt_ctf_event_borrow_packet(event)) {
+               goto error;
+       }
+
+       notification = g_new0(struct bt_notification_event, 1);
+       if (!notification) {
+               goto error;
+       }
+       bt_notification_init(&notification->parent,
+                       BT_NOTIFICATION_TYPE_EVENT,
+                       bt_notification_event_destroy);
+       notification->event = bt_get(event);
+       notification->cc_prio_map = bt_get(cc_prio_map);
+       if (!validate_clock_classes(notification)) {
+               goto error;
+       }
+
+       bt_ctf_event_freeze(notification->event);
+       return &notification->parent;
+error:
+       bt_put(notification);
+       return NULL;
+}
+
+struct bt_ctf_event *bt_notification_event_get_event(
+               struct bt_notification *notification)
+{
+       struct bt_ctf_event *event = NULL;
+       struct bt_notification_event *event_notification;
+
+       if (bt_notification_get_type(notification) !=
+                       BT_NOTIFICATION_TYPE_EVENT) {
+               goto end;
+       }
+       event_notification = container_of(notification,
+                       struct bt_notification_event, parent);
+       event = bt_get(event_notification->event);
+end:
+       return event;
+}
+
+extern struct bt_clock_class_priority_map *
+bt_notification_event_get_clock_class_priority_map(
+               struct bt_notification *notification)
+{
+       struct bt_clock_class_priority_map *cc_prio_map = NULL;
+       struct bt_notification_event *event_notification;
+
+       if (bt_notification_get_type(notification) !=
+                       BT_NOTIFICATION_TYPE_EVENT) {
+               goto end;
+       }
+
+       event_notification = container_of(notification,
+                       struct bt_notification_event, parent);
+       cc_prio_map = bt_get(event_notification->cc_prio_map);
+end:
+       return cc_prio_map;
+}
diff --git a/lib/graph/notification/heap.c b/lib/graph/notification/heap.c
new file mode 100644 (file)
index 0000000..fc0bce8
--- /dev/null
@@ -0,0 +1,264 @@
+/*
+ * Babeltrace - CTF notification priority heap
+ *
+ * Static-sized priority heap containing pointers. Based on CLRS,
+ * chapter 6.
+ *
+ * Copyright (c) 2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ * Copyright (c) 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <assert.h>
+#include <stddef.h>
+#include <babeltrace/compiler-internal.h>
+#include <babeltrace/graph/notification-heap-internal.h>
+
+#ifdef DEBUG_HEAP
+static
+void check_heap(struct bt_notification_heap *heap)
+{
+       size_t i;
+
+       if (!heap->count) {
+               return;
+       }
+
+       for (i = 1; i < heap->count; i++) {
+               assert(!heap->compare(g_ptr_array_index(heap->ptrs, i),
+                               g_ptr_array_index(heap->ptrs, 0),
+                               heap->compare_data));
+       }
+}
+#else
+void check_heap(struct bt_notification_heap *heap)
+{
+}
+#endif
+
+static
+size_t parent(size_t i)
+{
+       return (i - 1) >> 1;
+}
+
+static
+size_t left(size_t i)
+{
+       return (i << 1) + 1;
+}
+
+static
+size_t right(size_t i)
+{
+       return (i << 1) + 2;
+}
+
+/*
+ * Copy of heap->ptrs pointer is invalid after heap_grow.
+ */
+static
+int heap_grow(struct bt_notification_heap *heap, size_t new_len)
+{
+       size_t alloc_len;
+
+       if (likely(heap->ptrs->len >= new_len)) {
+               goto end;
+       }
+
+        alloc_len = max_t(size_t, new_len, heap->ptrs->len << 1);
+       g_ptr_array_set_size(heap->ptrs, alloc_len);
+end:
+       return 0;
+}
+
+static
+int heap_set_count(struct bt_notification_heap *heap, size_t new_count)
+{
+       int ret = 0;
+
+       ret = heap_grow(heap, new_count);
+       if (unlikely(ret)) {
+               goto end;
+       }
+       heap->count = new_count;
+end:
+       return ret;
+}
+
+static
+void heapify(struct bt_notification_heap *heap, size_t i)
+{
+       struct bt_notification **ptrs =
+                       (struct bt_notification **) heap->ptrs->pdata;
+
+       for (;;) {
+               void *tmp;
+               size_t l, r, largest;
+
+               l = left(i);
+               r = right(i);
+               if (l < heap->count && heap->compare(ptrs[l], ptrs[i],
+                               heap->compare_data)) {
+                       largest = l;
+               } else {
+                       largest = i;
+               }
+               if (r < heap->count && heap->compare(ptrs[r], ptrs[largest],
+                               heap->compare_data)) {
+                       largest = r;
+               }
+               if (unlikely(largest == i)) {
+                       break;
+               }
+               tmp = ptrs[i];
+               ptrs[i] = ptrs[largest];
+               ptrs[largest] = tmp;
+               i = largest;
+       }
+       check_heap(heap);
+}
+
+static
+struct bt_notification *heap_replace_max(struct bt_notification_heap *heap,
+               struct bt_notification *notification)
+{
+       struct bt_notification *res = NULL;
+
+       if (unlikely(!heap->count)) {
+               (void) heap_set_count(heap, 1);
+               g_ptr_array_index(heap->ptrs, 0) = notification;
+               check_heap(heap);
+               goto end;
+       }
+
+       /* Replace the current max and heapify. */
+       res = g_ptr_array_index(heap->ptrs, 0);
+       g_ptr_array_index(heap->ptrs, 0) = notification;
+       heapify(heap, 0);
+end:
+       return res;
+}
+
+static
+void bt_notification_heap_destroy(struct bt_object *obj)
+{
+       struct bt_notification_heap *heap = container_of(obj,
+                       struct bt_notification_heap, base);
+
+       if (heap->ptrs) {
+               size_t i;
+
+               for (i = 0; i < heap->count; i++) {
+                       bt_put(g_ptr_array_index(heap->ptrs, i));
+               }
+               g_ptr_array_free(heap->ptrs, TRUE);
+       }
+       g_free(heap);
+}
+
+struct bt_notification_heap *bt_notification_heap_create(
+               bt_notification_time_compare_func comparator, void *user_data)
+{
+       struct bt_notification_heap *heap = NULL;
+
+       if (!comparator) {
+               goto end;
+       }
+
+       heap = g_new0(struct bt_notification_heap, 1);
+       if (!heap) {
+               goto end;
+       }
+
+       bt_object_init(&heap->base, bt_notification_heap_destroy);
+       heap->ptrs = g_ptr_array_new();
+       if (!heap->ptrs) {
+               BT_PUT(heap);
+               goto end;
+       }
+
+       heap->compare = comparator;
+       heap->compare_data = user_data;
+end:
+       return heap;
+}
+
+struct bt_notification *bt_notification_heap_peek(
+               struct bt_notification_heap *heap)
+{
+       check_heap(heap);
+       return bt_get(likely(heap->count) ?
+                       g_ptr_array_index(heap->ptrs, 0) : NULL);
+}
+
+int bt_notification_heap_insert(struct bt_notification_heap *heap,
+               struct bt_notification *notification)
+{
+       int ret;
+       size_t pos;
+        struct bt_notification **ptrs;
+
+       ret = heap_set_count(heap, heap->count + 1);
+       if (unlikely(ret)) {
+               goto end;
+       }
+
+       ptrs = (struct bt_notification **) heap->ptrs->pdata;
+       pos = heap->count - 1;
+       while (pos > 0 && heap->compare(notification, ptrs[parent(pos)],
+                       heap->compare_data)) {
+               /* Move parent down until we find the right spot. */
+               ptrs[pos] = ptrs[parent(pos)];
+               pos = parent(pos);
+       }
+       ptrs[pos] = bt_get(notification);
+       check_heap(heap);
+end:
+       return ret;
+}
+
+struct bt_notification *bt_notification_heap_pop(
+               struct bt_notification_heap *heap)
+{
+        struct bt_notification *ret = NULL;
+
+       switch (heap->count) {
+       case 0:
+               goto end;
+       case 1:
+               (void) heap_set_count(heap, 0);
+               ret = g_ptr_array_index(heap->ptrs, 0);
+               goto end;
+       }
+       /*
+        * Shrink, replace the current max by previous last entry and heapify.
+        */
+       heap_set_count(heap, heap->count - 1);
+       /* count changed. previous last entry is at heap->count. */
+       ret = heap_replace_max(heap, g_ptr_array_index(heap->ptrs,
+                       heap->count));
+end:
+       /*
+        * Not taking a supplementary reference since we are relinquishing our
+        * own to the caller.
+        */
+       return ret;
+}
diff --git a/lib/graph/notification/inactivity.c b/lib/graph/notification/inactivity.c
new file mode 100644 (file)
index 0000000..4807395
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2017 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/object-internal.h>
+#include <babeltrace/compiler-internal.h>
+#include <babeltrace/ctf-ir/clock-class.h>
+#include <babeltrace/graph/clock-class-priority-map.h>
+#include <babeltrace/graph/notification-internal.h>
+#include <babeltrace/graph/notification-inactivity-internal.h>
+
+static
+void bt_notification_inactivity_destroy(struct bt_object *obj)
+{
+       struct bt_notification_inactivity *notification =
+                       (struct bt_notification_inactivity *) obj;
+
+       bt_put(notification->cc_prio_map);
+
+       if (notification->clock_values) {
+               g_hash_table_destroy(notification->clock_values);
+       }
+
+       g_free(notification);
+}
+
+struct bt_notification *bt_notification_inactivity_create(
+               struct bt_clock_class_priority_map *cc_prio_map)
+{
+       struct bt_notification_inactivity *notification;
+       struct bt_notification *ret_notif = NULL;
+
+       if (!cc_prio_map) {
+               goto error;
+       }
+
+       notification = g_new0(struct bt_notification_inactivity, 1);
+       if (!notification) {
+               goto error;
+       }
+       bt_notification_init(&notification->parent,
+                       BT_NOTIFICATION_TYPE_INACTIVITY,
+                       bt_notification_inactivity_destroy);
+       ret_notif = &notification->parent;
+       notification->clock_values = g_hash_table_new_full(g_direct_hash,
+                       g_direct_equal, bt_put, bt_put);
+       if (!notification->clock_values) {
+               goto error;
+       }
+
+       notification->cc_prio_map = bt_get(cc_prio_map);
+       goto end;
+
+error:
+       BT_PUT(ret_notif);
+
+end:
+       return ret_notif;
+}
+
+extern struct bt_clock_class_priority_map *
+bt_notification_inactivity_get_clock_class_priority_map(
+               struct bt_notification *notification)
+{
+       struct bt_clock_class_priority_map *cc_prio_map = NULL;
+       struct bt_notification_inactivity *inactivity_notification;
+
+       if (bt_notification_get_type(notification) !=
+                       BT_NOTIFICATION_TYPE_INACTIVITY) {
+               goto end;
+       }
+
+       inactivity_notification = container_of(notification,
+                       struct bt_notification_inactivity, parent);
+       cc_prio_map = bt_get(inactivity_notification->cc_prio_map);
+end:
+       return cc_prio_map;
+}
+
+struct bt_ctf_clock_value *bt_notification_inactivity_get_clock_value(
+               struct bt_notification *notification,
+               struct bt_ctf_clock_class *clock_class)
+{
+       struct bt_ctf_clock_value *clock_value = NULL;
+       struct bt_notification_inactivity *inactivity_notification;
+
+       if (!notification || !clock_class) {
+               goto end;
+       }
+
+       if (bt_notification_get_type(notification) !=
+                       BT_NOTIFICATION_TYPE_INACTIVITY) {
+               goto end;
+       }
+
+       inactivity_notification = container_of(notification,
+                       struct bt_notification_inactivity, parent);
+       clock_value = g_hash_table_lookup(inactivity_notification->clock_values,
+               clock_class);
+       bt_get(clock_value);
+
+end:
+       return clock_value;
+}
+
+int bt_notification_inactivity_set_clock_value(
+               struct bt_notification *notification,
+               struct bt_ctf_clock_value *clock_value)
+{
+       int ret = 0;
+       uint64_t prio;
+       struct bt_ctf_clock_class *clock_class = NULL;
+       struct bt_notification_inactivity *inactivity_notification;
+
+       if (!notification || !clock_value || notification->frozen) {
+               ret = -1;
+               goto end;
+       }
+
+       if (bt_notification_get_type(notification) !=
+                       BT_NOTIFICATION_TYPE_INACTIVITY) {
+               goto end;
+       }
+
+       inactivity_notification = container_of(notification,
+                       struct bt_notification_inactivity, parent);
+       clock_class = bt_ctf_clock_value_get_class(clock_value);
+       ret = bt_clock_class_priority_map_get_clock_class_priority(
+               inactivity_notification->cc_prio_map, clock_class, &prio);
+       if (ret) {
+               /*
+                * Clock value's class is not mapped to a priority
+                * within the scope of this notification.
+                */
+               goto end;
+       }
+
+       g_hash_table_insert(inactivity_notification->clock_values,
+               clock_class, bt_get(clock_value));
+       clock_class = NULL;
+
+end:
+       bt_put(clock_class);
+       return ret;
+}
diff --git a/lib/graph/notification/notification.c b/lib/graph/notification/notification.c
new file mode 100644 (file)
index 0000000..9dc64d7
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Babeltrace Plug-in Notification
+ *
+ * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/graph/notification-internal.h>
+
+BT_HIDDEN
+void bt_notification_init(struct bt_notification *notification,
+               enum bt_notification_type type,
+               bt_object_release_func release)
+{
+       assert(type > BT_NOTIFICATION_TYPE_ALL &&
+                       type < BT_NOTIFICATION_TYPE_NR);
+       notification->type = type;
+       bt_object_init(&notification->base, release);
+}
+
+enum bt_notification_type bt_notification_get_type(
+               struct bt_notification *notification)
+{
+       return notification ? notification->type : BT_NOTIFICATION_TYPE_UNKNOWN;
+}
+
+struct bt_ctf_stream *bt_notification_get_stream(
+               struct bt_notification *notification)
+{
+       struct bt_ctf_stream *stream = NULL;
+
+       if (!notification || !notification->get_stream) {
+               goto end;
+       }
+
+       stream = notification->get_stream(notification);
+end:
+       return stream;
+}
diff --git a/lib/graph/notification/packet.c b/lib/graph/notification/packet.c
new file mode 100644 (file)
index 0000000..fa6a0ee
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * Babeltrace Plug-in Packet-related Notifications
+ *
+ * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/compiler-internal.h>
+#include <babeltrace/graph/notification-packet-internal.h>
+
+static
+void bt_notification_packet_begin_destroy(struct bt_object *obj)
+{
+       struct bt_notification_packet_begin *notification =
+                       (struct bt_notification_packet_begin *) obj;
+
+       BT_PUT(notification->packet);
+       g_free(notification);
+}
+
+static
+void bt_notification_packet_end_destroy(struct bt_object *obj)
+{
+       struct bt_notification_packet_end *notification =
+                       (struct bt_notification_packet_end *) obj;
+
+       BT_PUT(notification->packet);
+       g_free(notification);
+}
+
+struct bt_notification *bt_notification_packet_begin_create(
+               struct bt_ctf_packet *packet)
+{
+       struct bt_notification_packet_begin *notification;
+
+       if (!packet) {
+               goto error;
+       }
+
+       notification = g_new0(struct bt_notification_packet_begin, 1);
+       bt_notification_init(&notification->parent,
+                       BT_NOTIFICATION_TYPE_PACKET_BEGIN,
+                       bt_notification_packet_begin_destroy);
+       notification->packet = bt_get(packet);
+       return &notification->parent;
+error:
+       return NULL;
+}
+
+struct bt_ctf_packet *bt_notification_packet_begin_get_packet(
+               struct bt_notification *notification)
+{
+       struct bt_ctf_packet *ret = NULL;
+       struct bt_notification_packet_begin *packet_begin;
+
+       if (notification->type != BT_NOTIFICATION_TYPE_PACKET_BEGIN) {
+               goto end;
+       }
+
+       packet_begin = container_of(notification,
+                       struct bt_notification_packet_begin, parent);
+       ret = bt_get(packet_begin->packet);
+end:
+       return ret;
+}
+
+struct bt_notification *bt_notification_packet_end_create(
+               struct bt_ctf_packet *packet)
+{
+       struct bt_notification_packet_end *notification;
+
+       if (!packet) {
+               goto error;
+       }
+
+       notification = g_new0(struct bt_notification_packet_end, 1);
+       bt_notification_init(&notification->parent,
+                       BT_NOTIFICATION_TYPE_PACKET_END,
+                       bt_notification_packet_end_destroy);
+       notification->packet = bt_get(packet);
+       return &notification->parent;
+error:
+       return NULL;
+}
+
+struct bt_ctf_packet *bt_notification_packet_end_get_packet(
+               struct bt_notification *notification)
+{
+       struct bt_ctf_packet *ret = NULL;
+       struct bt_notification_packet_end *packet_end;
+
+       if (notification->type != BT_NOTIFICATION_TYPE_PACKET_END) {
+               goto end;
+       }
+
+       packet_end = container_of(notification,
+                       struct bt_notification_packet_end, parent);
+       ret = bt_get(packet_end->packet);
+end:
+       return ret;
+}
diff --git a/lib/graph/notification/stream.c b/lib/graph/notification/stream.c
new file mode 100644 (file)
index 0000000..68b9bcd
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Babeltrace Plug-in Stream-related Notifications
+ *
+ * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/compiler-internal.h>
+#include <babeltrace/graph/notification-stream-internal.h>
+
+static
+void bt_notification_stream_end_destroy(struct bt_object *obj)
+{
+       struct bt_notification_stream_end *notification =
+                       (struct bt_notification_stream_end *) obj;
+
+       BT_PUT(notification->stream);
+       g_free(notification);
+}
+
+struct bt_notification *bt_notification_stream_end_create(
+               struct bt_ctf_stream *stream)
+{
+       struct bt_notification_stream_end *notification;
+
+       if (!stream) {
+               goto error;
+       }
+
+       notification = g_new0(struct bt_notification_stream_end, 1);
+       bt_notification_init(&notification->parent,
+                       BT_NOTIFICATION_TYPE_STREAM_END,
+                       bt_notification_stream_end_destroy);
+       notification->stream = bt_get(stream);
+       return &notification->parent;
+error:
+       return NULL;
+}
+
+struct bt_ctf_packet *bt_notification_stream_end_get_stream(
+               struct bt_notification *notification)
+{
+       struct bt_notification_stream_end *stream_end;
+
+       stream_end = container_of(notification,
+                       struct bt_notification_stream_end, parent);
+       return bt_get(stream_end->stream);
+}
diff --git a/lib/graph/port.c b/lib/graph/port.c
new file mode 100644 (file)
index 0000000..c0d5e06
--- /dev/null
@@ -0,0 +1,212 @@
+/*
+ * port.c
+ *
+ * Babeltrace Port
+ *
+ * Copyright 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/graph/component-internal.h>
+#include <babeltrace/graph/port-internal.h>
+#include <babeltrace/graph/connection-internal.h>
+#include <babeltrace/object-internal.h>
+#include <babeltrace/compiler-internal.h>
+
+static
+void bt_port_destroy(struct bt_object *obj)
+{
+       struct bt_port *port = container_of(obj, struct bt_port, base);
+
+       if (port->name) {
+               g_string_free(port->name, TRUE);
+       }
+       g_free(port);
+}
+
+struct bt_port *bt_port_from_private_port(
+               struct bt_private_port *private_port)
+{
+       return bt_get(bt_port_from_private(private_port));
+}
+
+BT_HIDDEN
+struct bt_port *bt_port_create(struct bt_component *parent_component,
+               enum bt_port_type type, const char *name)
+{
+       struct bt_port *port = NULL;
+
+       assert(name);
+       assert(parent_component);
+       assert(type == BT_PORT_TYPE_INPUT || type == BT_PORT_TYPE_OUTPUT);
+
+       if (strlen(name) == 0) {
+               goto end;
+       }
+
+       port = g_new0(struct bt_port, 1);
+       if (!port) {
+               goto end;
+       }
+
+       bt_object_init(port, bt_port_destroy);
+       port->name = g_string_new(name);
+       if (!port->name) {
+               BT_PUT(port);
+               goto end;
+       }
+
+       port->type = type;
+
+       bt_object_set_parent(port, &parent_component->base);
+end:
+       return port;
+}
+
+const char *bt_port_get_name(struct bt_port *port)
+{
+       return port ? port->name->str : NULL;
+}
+
+enum bt_port_type bt_port_get_type(struct bt_port *port)
+{
+       return port ? port->type : BT_PORT_TYPE_UNKOWN;
+}
+
+struct bt_connection *bt_port_get_connection(struct bt_port *port)
+{
+       struct bt_connection *connection = NULL;
+
+       if (!port || !port->connection) {
+               goto end;
+       }
+
+       connection = bt_get(port->connection);
+end:
+       return connection;
+}
+
+struct bt_component *bt_port_get_component(struct bt_port *port)
+{
+       return (struct bt_component *) bt_object_get_parent(port);
+}
+
+struct bt_private_connection *bt_private_port_get_private_connection(
+               struct bt_private_port *private_port)
+{
+       return bt_private_connection_from_connection(bt_port_get_connection(
+               bt_port_from_private(private_port)));
+}
+
+struct bt_private_component *bt_private_port_get_private_component(
+               struct bt_private_port *private_port)
+{
+       return bt_private_component_from_component(bt_port_get_component(
+               bt_port_from_private(private_port)));
+}
+
+BT_HIDDEN
+void bt_port_set_connection(struct bt_port *port,
+               struct bt_connection *connection)
+{
+       /*
+        * Don't take a reference on connection as its existence is
+        * guaranteed by the existence of the graph in which the
+        * connection exists.
+        */
+       port->connection = connection;
+}
+
+int bt_private_port_remove_from_component(
+               struct bt_private_port *private_port)
+{
+       int ret = 0;
+       struct bt_port *port = bt_port_from_private(private_port);
+       struct bt_component *comp = NULL;
+
+       if (!port) {
+               ret = -1;
+               goto end;
+       }
+
+       comp = (void *) bt_object_get_parent(port);
+       ret = bt_component_remove_port(comp, port);
+
+end:
+       bt_put(comp);
+       return ret;
+}
+
+int bt_port_disconnect(struct bt_port *port)
+{
+       int ret = 0;
+
+       if (!port) {
+               ret = -1;
+               goto end;
+       }
+
+       if (port->connection) {
+               bt_connection_disconnect_ports(port->connection);
+       }
+
+end:
+       return ret;
+}
+
+int bt_port_is_connected(struct bt_port *port)
+{
+       int ret;
+
+       if (!port) {
+               ret = -1;
+               goto end;
+       }
+
+       ret = port->connection ? 1 : 0;
+
+end:
+       return ret;
+}
+
+int bt_private_port_set_user_data(
+               struct bt_private_port *private_port, void *user_data)
+{
+       int ret = 0;
+
+       if (!private_port) {
+               ret = -1;
+               goto end;
+       }
+
+       bt_port_from_private(private_port)->user_data = user_data;
+
+end:
+       return ret;
+}
+
+void *bt_private_port_get_user_data(
+               struct bt_private_port *private_port)
+{
+       return private_port ?
+               bt_port_from_private(private_port)->user_data : NULL;
+}
diff --git a/lib/graph/sink.c b/lib/graph/sink.c
new file mode 100644 (file)
index 0000000..49bd840
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ * sink.c
+ *
+ * Babeltrace Sink Component
+ *
+ * Copyright 2015 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/compiler-internal.h>
+#include <babeltrace/values.h>
+#include <babeltrace/graph/component-sink-internal.h>
+#include <babeltrace/graph/component-internal.h>
+#include <babeltrace/graph/notification.h>
+
+BT_HIDDEN
+enum bt_component_status bt_component_sink_validate(
+               struct bt_component *component)
+{
+       enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
+
+       if (!component) {
+               ret = BT_COMPONENT_STATUS_INVALID;
+               goto end;
+       }
+
+       if (!component->class) {
+               ret = BT_COMPONENT_STATUS_INVALID;
+               goto end;
+       }
+
+       if (component->class->type != BT_COMPONENT_CLASS_TYPE_SINK) {
+               ret = BT_COMPONENT_STATUS_INVALID;
+               goto end;
+       }
+end:
+       return ret;
+}
+
+BT_HIDDEN
+void bt_component_sink_destroy(struct bt_component *component)
+{
+}
+
+BT_HIDDEN
+struct bt_component *bt_component_sink_create(
+               struct bt_component_class *class, struct bt_value *params)
+{
+       struct bt_component_sink *sink = NULL;
+
+       sink = g_new0(struct bt_component_sink, 1);
+       if (!sink) {
+               goto end;
+       }
+
+end:
+       return sink ? &sink->parent : NULL;
+}
+
+BT_HIDDEN
+enum bt_component_status bt_component_sink_consume(
+               struct bt_component *component)
+{
+       enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
+       struct bt_component_class_sink *sink_class = NULL;
+
+       if (!component) {
+               ret = BT_COMPONENT_STATUS_INVALID;
+               goto end;
+       }
+
+       if (bt_component_get_class_type(component) != BT_COMPONENT_CLASS_TYPE_SINK) {
+               ret = BT_COMPONENT_STATUS_UNSUPPORTED;
+               goto end;
+       }
+
+       sink_class = container_of(component->class, struct bt_component_class_sink, parent);
+       assert(sink_class->methods.consume);
+       ret = sink_class->methods.consume(bt_private_component_from_component(component));
+end:
+       return ret;
+}
+
+enum bt_component_status bt_component_sink_get_input_port_count(
+               struct bt_component *component, uint64_t *count)
+{
+       enum bt_component_status status = BT_COMPONENT_STATUS_OK;
+
+       if (!component || !count ||
+                       component->class->type != BT_COMPONENT_CLASS_TYPE_SINK) {
+               status = BT_COMPONENT_STATUS_INVALID;
+               goto end;
+       }
+
+       *count = bt_component_get_input_port_count(component);
+end:
+       return status;
+}
+
+struct bt_port *bt_component_sink_get_input_port(
+               struct bt_component *component, const char *name)
+{
+       struct bt_port *port = NULL;
+
+       if (!component || !name ||
+                       component->class->type != BT_COMPONENT_CLASS_TYPE_SINK) {
+               goto end;
+       }
+
+       port = bt_component_get_input_port(component, name);
+end:
+       return port;
+}
+
+struct bt_port *bt_component_sink_get_input_port_at_index(
+               struct bt_component *component, int index)
+{
+       struct bt_port *port = NULL;
+
+       if (!component ||
+                       component->class->type != BT_COMPONENT_CLASS_TYPE_SINK) {
+               goto end;
+       }
+
+       port = bt_component_get_input_port_at_index(component, index);
+end:
+       return port;
+}
+
+struct bt_port *bt_component_sink_get_default_input_port(
+               struct bt_component *component)
+{
+       return bt_component_sink_get_input_port(component,
+                       DEFAULT_INPUT_PORT_NAME);
+}
+
+struct bt_private_port *
+bt_private_component_sink_get_input_private_port_at_index(
+               struct bt_private_component *private_component, int index)
+{
+       return bt_private_port_from_port(
+               bt_component_sink_get_input_port_at_index(
+                       bt_component_from_private(private_component), index));
+}
+
+struct bt_private_port *bt_private_component_sink_get_default_input_private_port(
+               struct bt_private_component *private_component)
+{
+       return bt_private_port_from_port(
+               bt_component_sink_get_default_input_port(
+                       bt_component_from_private(private_component)));
+}
+
+struct bt_private_port *bt_private_component_sink_add_input_private_port(
+               struct bt_private_component *private_component,
+               const char *name)
+{
+       struct bt_port *port = NULL;
+       struct bt_component *component =
+               bt_component_from_private(private_component);
+
+       if (!component ||
+                       component->class->type != BT_COMPONENT_CLASS_TYPE_SINK) {
+               goto end;
+       }
+
+       port = bt_component_add_input_port(component, name);
+end:
+       return bt_private_port_from_port(port);
+}
diff --git a/lib/graph/source.c b/lib/graph/source.c
new file mode 100644 (file)
index 0000000..0c4f181
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * source.c
+ *
+ * Babeltrace Source Component
+ *
+ * Copyright 2015 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <babeltrace/ref.h>
+#include <babeltrace/compiler-internal.h>
+#include <babeltrace/graph/component-source-internal.h>
+#include <babeltrace/graph/component-internal.h>
+#include <babeltrace/graph/port-internal.h>
+#include <babeltrace/graph/notification-iterator.h>
+#include <babeltrace/graph/notification-iterator-internal.h>
+
+BT_HIDDEN
+enum bt_component_status bt_component_source_validate(
+               struct bt_component *component)
+{
+       enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
+
+       if (!component) {
+               ret = BT_COMPONENT_STATUS_INVALID;
+               goto end;
+       }
+
+       if (!component->class) {
+               ret = BT_COMPONENT_STATUS_INVALID;
+               goto end;
+       }
+
+       if (component->class->type != BT_COMPONENT_CLASS_TYPE_SOURCE) {
+               ret = BT_COMPONENT_STATUS_INVALID;
+               goto end;
+       }
+
+end:
+       return ret;
+}
+
+BT_HIDDEN
+void bt_component_source_destroy(struct bt_component *component)
+{
+}
+
+BT_HIDDEN
+struct bt_component *bt_component_source_create(
+               struct bt_component_class *class, struct bt_value *params)
+{
+       struct bt_component_source *source = NULL;
+
+       source = g_new0(struct bt_component_source, 1);
+       if (!source) {
+               goto end;
+       }
+
+end:
+       return source ? &source->parent : NULL;
+}
+
+enum bt_component_status bt_component_source_get_output_port_count(
+               struct bt_component *component, uint64_t *count)
+{
+       enum bt_component_status status = BT_COMPONENT_STATUS_OK;
+
+       if (!component || !count ||
+                       component->class->type != BT_COMPONENT_CLASS_TYPE_SOURCE) {
+               status = BT_COMPONENT_STATUS_INVALID;
+               goto end;
+       }
+
+       *count = bt_component_get_output_port_count(component);
+end:
+       return status;
+}
+
+struct bt_port *bt_component_source_get_output_port(
+               struct bt_component *component, const char *name)
+{
+       struct bt_port *port = NULL;
+
+       if (!component || !name ||
+                       component->class->type != BT_COMPONENT_CLASS_TYPE_SOURCE) {
+               goto end;
+       }
+
+       port = bt_component_get_output_port(component, name);
+end:
+       return port;
+}
+
+struct bt_port *bt_component_source_get_output_port_at_index(
+               struct bt_component *component, int index)
+{
+       struct bt_port *port = NULL;
+
+       if (!component ||
+                       component->class->type != BT_COMPONENT_CLASS_TYPE_SOURCE) {
+               goto end;
+       }
+
+       port = bt_component_get_output_port_at_index(component, index);
+end:
+       return port;
+}
+
+struct bt_port *bt_component_source_get_default_output_port(
+               struct bt_component *component)
+{
+       return bt_component_source_get_output_port(component,
+                       DEFAULT_OUTPUT_PORT_NAME);
+}
+
+struct bt_private_port *bt_private_component_source_get_output_private_port(
+               struct bt_private_component *private_component,
+               const char *name)
+{
+       return bt_private_port_from_port(bt_component_source_get_output_port(
+               bt_component_from_private(private_component), name));
+}
+
+struct bt_private_port *
+bt_private_component_source_get_output_private_port_at_index(
+               struct bt_private_component *private_component, int index)
+{
+       return bt_private_port_from_port(
+               bt_component_source_get_output_port_at_index(
+                       bt_component_from_private(private_component), index));
+}
+
+struct bt_private_port *bt_private_component_source_get_default_output_private_port(
+               struct bt_private_component *private_component)
+{
+       return bt_private_port_from_port(
+               bt_component_source_get_default_output_port(
+                       bt_component_from_private(private_component)));
+}
+
+struct bt_private_port *bt_private_component_source_add_output_private_port(
+               struct bt_private_component *private_component,
+               const char *name)
+{
+       struct bt_port *port = NULL;
+       struct bt_component *component =
+               bt_component_from_private(private_component);
+
+       if (!component ||
+                       component->class->type != BT_COMPONENT_CLASS_TYPE_SOURCE) {
+               goto end;
+       }
+
+       port = bt_component_add_output_port(component, name);
+end:
+       return bt_private_port_from_port(port);
+}
This page took 0.12582 seconds and 4 git commands to generate.