BT_GRAPH_STATUS_CANCELED is not an error, thus use a positive value
[babeltrace.git] / lib / graph / connection.c
CommitLineData
784cdc68 1/*
7d55361f 2 * connection.c
784cdc68
JG
3 *
4 * Babeltrace Connection
5 *
6 * Copyright 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
7 *
8 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 * of this software and associated documentation files (the "Software"), to deal
12 * in the Software without restriction, including without limitation the rights
13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the Software is
15 * furnished to do so, subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 * SOFTWARE.
27 */
28
b2e0c907
PP
29#include <babeltrace/graph/notification-iterator-internal.h>
30#include <babeltrace/graph/component-internal.h>
31#include <babeltrace/graph/component-source-internal.h>
32#include <babeltrace/graph/component-filter-internal.h>
33#include <babeltrace/graph/connection-internal.h>
34#include <babeltrace/graph/private-connection.h>
35#include <babeltrace/graph/graph-internal.h>
36#include <babeltrace/graph/port-internal.h>
784cdc68 37#include <babeltrace/object-internal.h>
3d9990ac 38#include <babeltrace/compiler-internal.h>
784cdc68
JG
39#include <glib.h>
40
41static
42void bt_connection_destroy(struct bt_object *obj)
43{
44 struct bt_connection *connection = container_of(obj,
45 struct bt_connection, base);
46
47 /*
48 * No bt_put on ports as a connection only holds _weak_ references
49 * to them.
50 */
51 g_free(connection);
52}
53
890882ef
PP
54struct bt_connection *bt_connection_from_private_connection(
55 struct bt_private_connection *private_connection)
56{
57 return bt_get(bt_connection_from_private(private_connection));
58}
59
784cdc68
JG
60BT_HIDDEN
61struct bt_connection *bt_connection_create(
62 struct bt_graph *graph,
72b913fb
PP
63 struct bt_port *upstream_port,
64 struct bt_port *downstream_port)
784cdc68
JG
65{
66 struct bt_connection *connection = NULL;
67
72b913fb 68 if (bt_port_get_type(upstream_port) != BT_PORT_TYPE_OUTPUT) {
784cdc68
JG
69 goto end;
70 }
72b913fb 71 if (bt_port_get_type(downstream_port) != BT_PORT_TYPE_INPUT) {
784cdc68
JG
72 goto end;
73 }
74
75 connection = g_new0(struct bt_connection, 1);
76 if (!connection) {
77 goto end;
78 }
79
80 bt_object_init(connection, bt_connection_destroy);
81 /* Weak references are taken, see comment in header. */
72b913fb
PP
82 connection->upstream_port = upstream_port;
83 connection->downstream_port = downstream_port;
84 bt_port_set_connection(upstream_port, connection);
85 bt_port_set_connection(downstream_port, connection);
784cdc68
JG
86 bt_object_set_parent(connection, &graph->base);
87end:
88 return connection;
89}
90
72b913fb 91BT_HIDDEN
2038affb 92void bt_connection_disconnect_ports(struct bt_connection *conn)
72b913fb
PP
93{
94 struct bt_component *downstream_comp = NULL;
95 struct bt_component *upstream_comp = NULL;
96 struct bt_port *downstream_port = conn->downstream_port;
97 struct bt_port *upstream_port = conn->upstream_port;
f345f8bb 98 struct bt_graph *graph = (void *) bt_object_get_parent(conn);
72b913fb
PP
99
100 if (downstream_port) {
101 downstream_comp = bt_port_get_component(downstream_port);
102 bt_port_set_connection(downstream_port, NULL);
103 conn->downstream_port = NULL;
104 }
105
106 if (upstream_port) {
107 upstream_comp = bt_port_get_component(upstream_port);
108 bt_port_set_connection(upstream_port, NULL);
109 conn->upstream_port = NULL;
110 }
111
2038affb 112 if (downstream_comp) {
72b913fb
PP
113 bt_component_port_disconnected(downstream_comp,
114 downstream_port);
115 }
116
2038affb 117 if (upstream_comp) {
72b913fb
PP
118 bt_component_port_disconnected(upstream_comp, upstream_port);
119 }
120
f345f8bb
PP
121 assert(graph);
122 bt_graph_notify_ports_disconnected(graph, upstream_comp,
123 downstream_comp, upstream_port, downstream_port);
72b913fb
PP
124 bt_put(downstream_comp);
125 bt_put(upstream_comp);
f345f8bb 126 bt_put(graph);
72b913fb
PP
127}
128
129struct bt_port *bt_connection_get_upstream_port(
784cdc68
JG
130 struct bt_connection *connection)
131{
72b913fb 132 return connection ? bt_get(connection->upstream_port) : NULL;
784cdc68
JG
133}
134
72b913fb 135struct bt_port *bt_connection_get_downstream_port(
784cdc68
JG
136 struct bt_connection *connection)
137{
72b913fb 138 return connection ? bt_get(connection->downstream_port) : NULL;
784cdc68
JG
139}
140
141struct bt_notification_iterator *
890882ef 142bt_private_connection_create_notification_iterator(
fa054faf
PP
143 struct bt_private_connection *private_connection,
144 const enum bt_notification_type *notification_types)
784cdc68 145{
890882ef
PP
146 enum bt_notification_iterator_status ret_iterator;
147 enum bt_component_class_type upstream_comp_class_type;
148 struct bt_notification_iterator *iterator = NULL;
149 struct bt_port *upstream_port = NULL;
784cdc68 150 struct bt_component *upstream_component = NULL;
890882ef
PP
151 struct bt_component_class *upstream_comp_class = NULL;
152 struct bt_connection *connection = NULL;
153 bt_component_class_notification_iterator_init_method init_method = NULL;
fa054faf
PP
154 static const enum bt_notification_type all_notif_types[] = {
155 BT_NOTIFICATION_TYPE_ALL,
156 BT_NOTIFICATION_TYPE_SENTINEL,
157 };
784cdc68 158
890882ef
PP
159 if (!private_connection) {
160 goto error;
784cdc68
JG
161 }
162
fa054faf
PP
163 if (!notification_types) {
164 notification_types = all_notif_types;
165 }
166
890882ef
PP
167 connection = bt_connection_from_private(private_connection);
168
72b913fb 169 if (!connection->upstream_port || !connection->downstream_port) {
890882ef 170 goto error;
72b913fb
PP
171 }
172
890882ef
PP
173 upstream_port = connection->upstream_port;
174 assert(upstream_port);
175 upstream_component = bt_port_get_component(upstream_port);
784cdc68 176 assert(upstream_component);
890882ef
PP
177 upstream_comp_class = upstream_component->class;
178
179 if (!upstream_component) {
180 goto error;
181 }
182
183 upstream_comp_class_type =
184 bt_component_get_class_type(upstream_component);
185 if (upstream_comp_class_type != BT_COMPONENT_CLASS_TYPE_SOURCE &&
186 upstream_comp_class_type != BT_COMPONENT_CLASS_TYPE_FILTER) {
187 /* Unsupported operation. */
188 goto error;
189 }
784cdc68 190
3230ee6b 191 iterator = bt_notification_iterator_create(upstream_component,
fa054faf 192 upstream_port, notification_types);
890882ef
PP
193 if (!iterator) {
194 goto error;
195 }
196
197 switch (upstream_comp_class_type) {
784cdc68 198 case BT_COMPONENT_CLASS_TYPE_SOURCE:
890882ef
PP
199 {
200 struct bt_component_class_source *source_class =
201 container_of(upstream_comp_class,
202 struct bt_component_class_source, parent);
203 init_method = source_class->methods.iterator.init;
784cdc68 204 break;
890882ef 205 }
784cdc68 206 case BT_COMPONENT_CLASS_TYPE_FILTER:
890882ef
PP
207 {
208 struct bt_component_class_filter *filter_class =
209 container_of(upstream_comp_class,
210 struct bt_component_class_filter, parent);
211 init_method = filter_class->methods.iterator.init;
784cdc68 212 break;
890882ef 213 }
784cdc68 214 default:
890882ef
PP
215 /* Unreachable. */
216 assert(0);
217 }
218
219 if (init_method) {
220 enum bt_notification_iterator_status status = init_method(
91457551
PP
221 bt_private_notification_iterator_from_notification_iterator(iterator),
222 bt_private_port_from_port(upstream_port));
890882ef
PP
223 if (status < 0) {
224 goto error;
225 }
226 }
227
228 ret_iterator = bt_notification_iterator_validate(iterator);
229 if (ret_iterator != BT_NOTIFICATION_ITERATOR_STATUS_OK) {
230 goto error;
784cdc68 231 }
890882ef
PP
232
233 goto end;
234
235error:
236 BT_PUT(iterator);
237
784cdc68
JG
238end:
239 bt_put(upstream_component);
890882ef 240 return iterator;
784cdc68 241}
This page took 0.035024 seconds and 4 git commands to generate.