+ }
+ /* 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;