Fix: ctf plugin: returning bt_message_iterator_status from src.ctf.fs
[babeltrace.git] / lib / graph / iterator.c
CommitLineData
47e5a032 1/*
e2f7325d 2 * Copyright 2017-2018 Philippe Proulx <pproulx@efficios.com>
47e5a032 3 * Copyright 2015 Jérémie Galarneau <jeremie.galarneau@efficios.com>
47e5a032
JG
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 */
23
d6e69534 24#define BT_LOG_TAG "MSG-ITER"
5af447e5
PP
25#include <babeltrace/lib-logging-internal.h>
26
3d9990ac 27#include <babeltrace/compiler-internal.h>
c6bd8523 28#include <babeltrace/trace-ir/field.h>
40f4ba76 29#include <babeltrace/trace-ir/event-const.h>
56e18c4c 30#include <babeltrace/trace-ir/event-internal.h>
40f4ba76 31#include <babeltrace/trace-ir/packet-const.h>
56e18c4c
PP
32#include <babeltrace/trace-ir/packet-internal.h>
33#include <babeltrace/trace-ir/stream-internal.h>
0d72b8c3 34#include <babeltrace/graph/connection-const.h>
bd14d768 35#include <babeltrace/graph/connection-internal.h>
0d72b8c3 36#include <babeltrace/graph/component-const.h>
e5be10ef 37#include <babeltrace/graph/component-internal.h>
b2e0c907
PP
38#include <babeltrace/graph/component-source-internal.h>
39#include <babeltrace/graph/component-class-internal.h>
8ed535b5 40#include <babeltrace/graph/component-class-sink-colander-internal.h>
0d72b8c3 41#include <babeltrace/graph/component-sink-const.h>
d6e69534
PP
42#include <babeltrace/graph/message-const.h>
43#include <babeltrace/graph/message-iterator.h>
44#include <babeltrace/graph/message-iterator-internal.h>
45#include <babeltrace/graph/self-component-port-input-message-iterator.h>
46#include <babeltrace/graph/port-output-message-iterator.h>
47#include <babeltrace/graph/message-internal.h>
48#include <babeltrace/graph/message-event-const.h>
49#include <babeltrace/graph/message-event-internal.h>
50#include <babeltrace/graph/message-packet-const.h>
51#include <babeltrace/graph/message-packet-internal.h>
52#include <babeltrace/graph/message-stream-const.h>
53#include <babeltrace/graph/message-stream-internal.h>
0d72b8c3
PP
54#include <babeltrace/graph/port-const.h>
55#include <babeltrace/graph/graph.h>
56#include <babeltrace/graph/graph-const.h>
8ed535b5 57#include <babeltrace/graph/graph-internal.h>
c55a9f58 58#include <babeltrace/types.h>
f6ccaed9 59#include <babeltrace/assert-internal.h>
f42867e2 60#include <babeltrace/assert-pre-internal.h>
fa054faf 61#include <stdint.h>
2ec84d26 62#include <inttypes.h>
0fbb9a9f 63#include <stdlib.h>
3230ee6b 64
d4393e08
PP
65/*
66 * TODO: Use graph's state (number of active iterators, etc.) and
67 * possibly system specifications to make a better guess than this.
68 */
d6e69534 69#define MSG_BATCH_SIZE 15
d4393e08 70
3230ee6b 71struct stream_state {
40f4ba76
PP
72 const struct bt_stream *stream; /* owned by this */
73 const struct bt_packet *cur_packet; /* owned by this */
d6e69534 74 uint64_t expected_msg_seq_num;
c55a9f58 75 bt_bool is_ended;
3230ee6b
PP
76};
77
26e21a82 78BT_ASSERT_PRE_FUNC
3230ee6b
PP
79static
80void destroy_stream_state(struct stream_state *stream_state)
81{
82 if (!stream_state) {
83 return;
84 }
85
5af447e5
PP
86 BT_LOGV("Destroying stream state: stream-state-addr=%p", stream_state);
87 BT_LOGV_STR("Putting stream state's current packet.");
d94d92ac 88 BT_OBJECT_PUT_REF_AND_RESET(stream_state->cur_packet);
5af447e5 89 BT_LOGV_STR("Putting stream state's stream.");
d94d92ac 90 BT_OBJECT_PUT_REF_AND_RESET(stream_state->stream);
3230ee6b
PP
91 g_free(stream_state);
92}
93
26e21a82 94BT_ASSERT_PRE_FUNC
3230ee6b 95static
40f4ba76 96struct stream_state *create_stream_state(const struct bt_stream *stream)
3230ee6b
PP
97{
98 struct stream_state *stream_state = g_new0(struct stream_state, 1);
99
100 if (!stream_state) {
5af447e5 101 BT_LOGE_STR("Failed to allocate one stream state.");
3230ee6b
PP
102 goto end;
103 }
104
105 /*
f42867e2 106 * We keep a reference to the stream until we know it's ended.
3230ee6b 107 */
398454ed
PP
108 stream_state->stream = stream;
109 bt_object_get_no_null_check(stream_state->stream);
d94d92ac 110 BT_LIB_LOGV("Created stream state: %![stream-]+s, "
5af447e5 111 "stream-state-addr=%p",
d94d92ac 112 stream, stream_state);
3230ee6b
PP
113
114end:
115 return stream_state;
116}
47e5a032 117
d0fea130
PP
118static inline
119void _set_self_comp_port_input_msg_iterator_state(
120 struct bt_self_component_port_input_message_iterator *iterator,
121 enum bt_self_component_port_input_message_iterator_state state)
122{
123 BT_ASSERT(iterator);
124 BT_LIB_LOGD("Updating message iterator's state: "
125 "new-state=%s",
126 bt_self_component_port_input_message_iterator_state_string(state));
127 iterator->state = state;
128}
129
130#ifdef BT_DEV_MODE
131# define set_self_comp_port_input_msg_iterator_state _set_self_comp_port_input_msg_iterator_state
132#else
133# define set_self_comp_port_input_msg_iterator_state(_a, _b)
134#endif
135
8ed535b5 136static
d6e69534 137void destroy_base_message_iterator(struct bt_object *obj)
8ed535b5 138{
d6e69534 139 struct bt_message_iterator *iterator = (void *) obj;
d4393e08
PP
140
141 BT_ASSERT(iterator);
142
d6e69534
PP
143 if (iterator->msgs) {
144 g_ptr_array_free(iterator->msgs, TRUE);
145 iterator->msgs = NULL;
d4393e08
PP
146 }
147
148 g_free(iterator);
8ed535b5
PP
149}
150
47e5a032 151static
d6e69534 152void bt_self_component_port_input_message_iterator_destroy(struct bt_object *obj)
47e5a032 153{
d6e69534 154 struct bt_self_component_port_input_message_iterator *iterator;
8738a040 155
f6ccaed9 156 BT_ASSERT(obj);
d3eb6e8f 157
bd14d768 158 /*
d6e69534 159 * The message iterator's reference count is 0 if we're
bd14d768
PP
160 * here. Increment it to avoid a double-destroy (possibly
161 * infinitely recursive). This could happen for example if the
d6e69534 162 * message iterator's finalization function does
d94d92ac
PP
163 * bt_object_get_ref() (or anything that causes
164 * bt_object_get_ref() to be called) on itself (ref. count goes
165 * from 0 to 1), and then bt_object_put_ref(): the reference
166 * count would go from 1 to 0 again and this function would be
167 * called again.
bd14d768 168 */
3fea54f6 169 obj->ref_count++;
07245ac2 170 iterator = (void *) obj;
d6e69534 171 BT_LIB_LOGD("Destroying self component input port message iterator object: "
d94d92ac 172 "%!+i", iterator);
d0fea130 173 bt_self_component_port_input_message_iterator_try_finalize(iterator);
d3eb6e8f 174
3230ee6b
PP
175 if (iterator->stream_states) {
176 /*
177 * Remove our destroy listener from each stream which
178 * has a state in this iterator. Otherwise the destroy
179 * listener would be called with an invalid/other
d6e69534 180 * message iterator object.
3230ee6b 181 */
3230ee6b 182 g_hash_table_destroy(iterator->stream_states);
d94d92ac 183 iterator->stream_states = NULL;
3230ee6b
PP
184 }
185
bd14d768
PP
186 if (iterator->connection) {
187 /*
188 * Remove ourself from the originating connection so
189 * that it does not try to finalize a dangling pointer
190 * later.
191 */
192 bt_connection_remove_iterator(iterator->connection, iterator);
d94d92ac 193 iterator->connection = NULL;
bd14d768
PP
194 }
195
d6e69534 196 destroy_base_message_iterator(obj);
47e5a032
JG
197}
198
bd14d768 199BT_HIDDEN
d0fea130 200void bt_self_component_port_input_message_iterator_try_finalize(
d6e69534 201 struct bt_self_component_port_input_message_iterator *iterator)
bd14d768 202{
d94d92ac
PP
203 typedef void (*method_t)(void *);
204
bd14d768 205 struct bt_component_class *comp_class = NULL;
d94d92ac 206 method_t method = NULL;
bd14d768 207
f6ccaed9 208 BT_ASSERT(iterator);
bd14d768
PP
209
210 switch (iterator->state) {
d6e69534 211 case BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_STATE_NON_INITIALIZED:
088d4023 212 /* Skip user finalization if user initialization failed */
d6e69534 213 BT_LIB_LOGD("Not finalizing non-initialized message iterator: "
d94d92ac 214 "%!+i", iterator);
d0fea130 215 goto end;
d6e69534 216 case BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_STATE_FINALIZED:
bd14d768 217 /* Already finalized */
d6e69534 218 BT_LIB_LOGD("Not finalizing message iterator: already finalized: "
d94d92ac 219 "%!+i", iterator);
d0fea130
PP
220 goto end;
221 case BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_STATE_FINALIZING:
222 /* Already finalized */
223 BT_LIB_LOGF("Message iterator is already being finalized: "
224 "%!+i", iterator);
225 abort();
bd14d768
PP
226 default:
227 break;
228 }
229
d6e69534 230 BT_LIB_LOGD("Finalizing message iterator: %!+i", iterator);
d0fea130
PP
231 set_self_comp_port_input_msg_iterator_state(iterator,
232 BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_STATE_FINALIZING);
f6ccaed9 233 BT_ASSERT(iterator->upstream_component);
bd14d768
PP
234 comp_class = iterator->upstream_component->class;
235
236 /* Call user-defined destroy method */
237 switch (comp_class->type) {
238 case BT_COMPONENT_CLASS_TYPE_SOURCE:
239 {
d94d92ac
PP
240 struct bt_component_class_source *src_comp_cls =
241 (void *) comp_class;
bd14d768 242
d6e69534 243 method = (method_t) src_comp_cls->methods.msg_iter_finalize;
bd14d768
PP
244 break;
245 }
246 case BT_COMPONENT_CLASS_TYPE_FILTER:
247 {
d94d92ac
PP
248 struct bt_component_class_filter *flt_comp_cls =
249 (void *) comp_class;
bd14d768 250
d6e69534 251 method = (method_t) flt_comp_cls->methods.msg_iter_finalize;
bd14d768
PP
252 break;
253 }
254 default:
255 /* Unreachable */
0fbb9a9f 256 abort();
bd14d768
PP
257 }
258
d94d92ac
PP
259 if (method) {
260 BT_LIB_LOGD("Calling user's finalization method: %!+i",
5af447e5 261 iterator);
d94d92ac 262 method(iterator);
bd14d768
PP
263 }
264
bd14d768
PP
265 iterator->upstream_component = NULL;
266 iterator->upstream_port = NULL;
d0fea130
PP
267 set_self_comp_port_input_msg_iterator_state(iterator,
268 BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_STATE_FINALIZED);
d6e69534 269 BT_LIB_LOGD("Finalized message iterator: %!+i", iterator);
d0fea130
PP
270
271end:
272 return;
bd14d768
PP
273}
274
275BT_HIDDEN
d6e69534
PP
276void bt_self_component_port_input_message_iterator_set_connection(
277 struct bt_self_component_port_input_message_iterator *iterator,
bd14d768
PP
278 struct bt_connection *connection)
279{
f6ccaed9 280 BT_ASSERT(iterator);
bd14d768 281 iterator->connection = connection;
d6e69534 282 BT_LIB_LOGV("Set message iterator's connection: "
d94d92ac 283 "%![iter-]+i, %![conn-]+x", iterator, connection);
bd14d768
PP
284}
285
90157d89 286static
d6e69534
PP
287int init_message_iterator(struct bt_message_iterator *iterator,
288 enum bt_message_iterator_type type,
90157d89
PP
289 bt_object_release_func destroy)
290{
d4393e08
PP
291 int ret = 0;
292
3fea54f6 293 bt_object_init_shared(&iterator->base, destroy);
90157d89 294 iterator->type = type;
d6e69534
PP
295 iterator->msgs = g_ptr_array_new();
296 if (!iterator->msgs) {
d4393e08
PP
297 BT_LOGE_STR("Failed to allocate a GPtrArray.");
298 ret = -1;
299 goto end;
300 }
301
d6e69534 302 g_ptr_array_set_size(iterator->msgs, MSG_BATCH_SIZE);
d4393e08
PP
303
304end:
305 return ret;
90157d89
PP
306}
307
d94d92ac 308static
d6e69534
PP
309struct bt_self_component_port_input_message_iterator *
310bt_self_component_port_input_message_iterator_create_initial(
3230ee6b 311 struct bt_component *upstream_comp,
d94d92ac 312 struct bt_port *upstream_port)
47e5a032 313{
d4393e08 314 int ret;
d6e69534 315 struct bt_self_component_port_input_message_iterator *iterator = NULL;
47e5a032 316
f6ccaed9
PP
317 BT_ASSERT(upstream_comp);
318 BT_ASSERT(upstream_port);
f6ccaed9 319 BT_ASSERT(bt_port_is_connected(upstream_port));
d6e69534 320 BT_LIB_LOGD("Creating initial message iterator on self component input port: "
d94d92ac
PP
321 "%![up-comp-]+c, %![up-port-]+p", upstream_comp, upstream_port);
322 BT_ASSERT(bt_component_get_class_type(upstream_comp) ==
323 BT_COMPONENT_CLASS_TYPE_SOURCE ||
324 bt_component_get_class_type(upstream_comp) ==
325 BT_COMPONENT_CLASS_TYPE_FILTER);
326 iterator = g_new0(
d6e69534 327 struct bt_self_component_port_input_message_iterator, 1);
47e5a032 328 if (!iterator) {
d94d92ac 329 BT_LOGE_STR("Failed to allocate one self component input port "
d6e69534 330 "message iterator.");
73d5c1ad 331 goto end;
47e5a032
JG
332 }
333
d6e69534
PP
334 ret = init_message_iterator((void *) iterator,
335 BT_MESSAGE_ITERATOR_TYPE_SELF_COMPONENT_PORT_INPUT,
336 bt_self_component_port_input_message_iterator_destroy);
d4393e08 337 if (ret) {
d6e69534 338 /* init_message_iterator() logs errors */
d94d92ac 339 BT_OBJECT_PUT_REF_AND_RESET(iterator);
d4393e08
PP
340 goto end;
341 }
3230ee6b
PP
342
343 iterator->stream_states = g_hash_table_new_full(g_direct_hash,
344 g_direct_equal, NULL, (GDestroyNotify) destroy_stream_state);
345 if (!iterator->stream_states) {
5af447e5 346 BT_LOGE_STR("Failed to allocate a GHashTable.");
d94d92ac 347 BT_OBJECT_PUT_REF_AND_RESET(iterator);
73d5c1ad 348 goto end;
3230ee6b
PP
349 }
350
bd14d768
PP
351 iterator->upstream_component = upstream_comp;
352 iterator->upstream_port = upstream_port;
d94d92ac 353 iterator->connection = iterator->upstream_port->connection;
5c563278 354 iterator->graph = bt_component_borrow_graph(upstream_comp);
d0fea130
PP
355 set_self_comp_port_input_msg_iterator_state(iterator,
356 BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_STATE_NON_INITIALIZED);
d6e69534 357 BT_LIB_LOGD("Created initial message iterator on self component input port: "
d94d92ac
PP
358 "%![up-port-]+p, %![up-comp-]+c, %![iter-]+i",
359 upstream_port, upstream_comp, iterator);
3230ee6b 360
47e5a032 361end:
d94d92ac 362 return iterator;
47e5a032
JG
363}
364
d6e69534
PP
365struct bt_self_component_port_input_message_iterator *
366bt_self_component_port_input_message_iterator_create(
d94d92ac 367 struct bt_self_component_port_input *self_port)
ea8d3e58 368{
d6e69534 369 typedef enum bt_self_message_iterator_status (*init_method_t)(
d94d92ac
PP
370 void *, void *, void *);
371
372 init_method_t init_method = NULL;
d6e69534 373 struct bt_self_component_port_input_message_iterator *iterator =
d94d92ac
PP
374 NULL;
375 struct bt_port *port = (void *) self_port;
376 struct bt_port *upstream_port;
377 struct bt_component *comp;
378 struct bt_component *upstream_comp;
379 struct bt_component_class *upstream_comp_cls;
380
381 BT_ASSERT_PRE_NON_NULL(port, "Port");
0d72b8c3 382 comp = bt_port_borrow_component_inline(port);
d94d92ac
PP
383 BT_ASSERT_PRE(bt_port_is_connected(port),
384 "Port is not connected: %![port-]+p", port);
385 BT_ASSERT_PRE(comp, "Port is not part of a component: %![port-]+p",
386 port);
387 BT_ASSERT_PRE(!bt_component_graph_is_canceled(comp),
388 "Port's component's graph is canceled: "
389 "%![port-]+p, %![comp-]+c", port, comp);
390 BT_ASSERT(port->connection);
391 upstream_port = port->connection->upstream_port;
392 BT_ASSERT(upstream_port);
0d72b8c3 393 upstream_comp = bt_port_borrow_component_inline(upstream_port);
d94d92ac
PP
394 BT_ASSERT(upstream_comp);
395 upstream_comp_cls = upstream_comp->class;
396 BT_ASSERT(upstream_comp->class->type ==
397 BT_COMPONENT_CLASS_TYPE_SOURCE ||
398 upstream_comp->class->type ==
399 BT_COMPONENT_CLASS_TYPE_FILTER);
d6e69534 400 iterator = bt_self_component_port_input_message_iterator_create_initial(
d94d92ac
PP
401 upstream_comp, upstream_port);
402 if (!iterator) {
403 BT_LOGW_STR("Cannot create self component input port "
d6e69534 404 "message iterator.");
d94d92ac
PP
405 goto end;
406 }
890882ef 407
d94d92ac
PP
408 switch (upstream_comp_cls->type) {
409 case BT_COMPONENT_CLASS_TYPE_SOURCE:
410 {
411 struct bt_component_class_source *src_comp_cls =
412 (void *) upstream_comp_cls;
413
414 init_method =
d6e69534 415 (init_method_t) src_comp_cls->methods.msg_iter_init;
d94d92ac
PP
416 break;
417 }
418 case BT_COMPONENT_CLASS_TYPE_FILTER:
419 {
420 struct bt_component_class_filter *flt_comp_cls =
421 (void *) upstream_comp_cls;
422
423 init_method =
d6e69534 424 (init_method_t) flt_comp_cls->methods.msg_iter_init;
d94d92ac
PP
425 break;
426 }
427 default:
428 /* Unreachable */
429 abort();
430 }
431
432 if (init_method) {
433 int iter_status;
434
435 BT_LIB_LOGD("Calling user's initialization method: %!+i", iterator);
436 iter_status = init_method(iterator, upstream_comp,
437 upstream_port);
438 BT_LOGD("User method returned: status=%s",
d6e69534
PP
439 bt_message_iterator_status_string(iter_status));
440 if (iter_status != BT_MESSAGE_ITERATOR_STATUS_OK) {
d94d92ac 441 BT_LOGW_STR("Initialization method failed.");
d0fea130 442 BT_OBJECT_PUT_REF_AND_RESET(iterator);
d94d92ac
PP
443 goto end;
444 }
445 }
446
d0fea130
PP
447 set_self_comp_port_input_msg_iterator_state(iterator,
448 BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_STATE_ACTIVE);
d94d92ac 449 g_ptr_array_add(port->connection->iterators, iterator);
d6e69534 450 BT_LIB_LOGD("Created message iterator on self component input port: "
d94d92ac
PP
451 "%![up-port-]+p, %![up-comp-]+c, %![iter-]+i",
452 upstream_port, upstream_comp, iterator);
453
454end:
455 return iterator;
ea8d3e58
JG
456}
457
d6e69534
PP
458void *bt_self_message_iterator_get_data(
459 const struct bt_self_message_iterator *self_iterator)
ea8d3e58 460{
d6e69534 461 struct bt_self_component_port_input_message_iterator *iterator =
d94d92ac 462 (void *) self_iterator;
ea8d3e58 463
d6e69534 464 BT_ASSERT_PRE_NON_NULL(iterator, "Message iterator");
d94d92ac 465 return iterator->user_data;
8738a040 466}
413bc2c4 467
d6e69534
PP
468void bt_self_message_iterator_set_data(
469 struct bt_self_message_iterator *self_iterator, void *data)
5c563278 470{
d6e69534 471 struct bt_self_component_port_input_message_iterator *iterator =
d94d92ac 472 (void *) self_iterator;
5c563278 473
d6e69534 474 BT_ASSERT_PRE_NON_NULL(iterator, "Message iterator");
d94d92ac 475 iterator->user_data = data;
d6e69534 476 BT_LIB_LOGV("Set message iterator's user data: "
d94d92ac 477 "%!+i, user-data-addr=%p", iterator, data);
5c563278
PP
478}
479
f42867e2
PP
480BT_ASSERT_PRE_FUNC
481static inline
d6e69534 482void bt_message_borrow_packet_stream(const struct bt_message *msg,
40f4ba76
PP
483 const struct bt_stream **stream,
484 const struct bt_packet **packet)
fa054faf 485{
d6e69534 486 BT_ASSERT(msg);
fa054faf 487
d6e69534
PP
488 switch (msg->type) {
489 case BT_MESSAGE_TYPE_EVENT:
40f4ba76 490 *packet = bt_event_borrow_packet_const(
d6e69534 491 bt_message_event_borrow_event_const(msg));
40f4ba76 492 *stream = bt_packet_borrow_stream_const(*packet);
fa054faf 493 break;
d6e69534
PP
494 case BT_MESSAGE_TYPE_STREAM_BEGINNING:
495 *stream = bt_message_stream_beginning_borrow_stream_const(msg);
fa054faf 496 break;
d6e69534
PP
497 case BT_MESSAGE_TYPE_STREAM_END:
498 *stream = bt_message_stream_end_borrow_stream_const(msg);
fa054faf 499 break;
d6e69534
PP
500 case BT_MESSAGE_TYPE_PACKET_BEGINNING:
501 *packet = bt_message_packet_beginning_borrow_packet_const(msg);
40f4ba76 502 *stream = bt_packet_borrow_stream_const(*packet);
fa054faf 503 break;
d6e69534
PP
504 case BT_MESSAGE_TYPE_PACKET_END:
505 *packet = bt_message_packet_end_borrow_packet_const(msg);
40f4ba76 506 *stream = bt_packet_borrow_stream_const(*packet);
2ec84d26 507 break;
fa054faf 508 default:
f42867e2 509 break;
fa054faf 510 }
fa054faf
PP
511}
512
f42867e2
PP
513BT_ASSERT_PRE_FUNC
514static inline
d6e69534
PP
515bool validate_message(
516 struct bt_self_component_port_input_message_iterator *iterator,
517 const struct bt_message *c_msg)
3230ee6b 518{
f42867e2 519 bool is_valid = true;
3230ee6b 520 struct stream_state *stream_state;
40f4ba76
PP
521 const struct bt_stream *stream = NULL;
522 const struct bt_packet *packet = NULL;
d6e69534 523 struct bt_message *msg = (void *) c_msg;
f42867e2 524
d6e69534
PP
525 BT_ASSERT(msg);
526 bt_message_borrow_packet_stream(c_msg, &stream, &packet);
f42867e2
PP
527
528 if (!stream) {
d6e69534 529 /* we don't care about messages not attached to streams */
f42867e2
PP
530 goto end;
531 }
3230ee6b 532
f42867e2
PP
533 stream_state = g_hash_table_lookup(iterator->stream_states, stream);
534 if (!stream_state) {
3230ee6b 535 /*
d6e69534
PP
536 * No stream state for this stream: this message
537 * MUST be a BT_MESSAGE_TYPE_STREAM_BEGINNING message
f42867e2 538 * and its sequence number must be 0.
3230ee6b 539 */
d6e69534
PP
540 if (c_msg->type != BT_MESSAGE_TYPE_STREAM_BEGINNING) {
541 BT_ASSERT_PRE_MSG("Unexpected message: missing a "
542 "BT_MESSAGE_TYPE_STREAM_BEGINNING "
543 "message prior to this message: "
f42867e2
PP
544 "%![stream-]+s", stream);
545 is_valid = false;
3230ee6b
PP
546 goto end;
547 }
548
d6e69534
PP
549 if (c_msg->seq_num == -1ULL) {
550 msg->seq_num = 0;
3230ee6b
PP
551 }
552
d6e69534
PP
553 if (c_msg->seq_num != 0) {
554 BT_ASSERT_PRE_MSG("Unexpected message sequence "
555 "number for this message iterator: "
556 "this is the first message for this "
f42867e2
PP
557 "stream, expecting sequence number 0: "
558 "seq-num=%" PRIu64 ", %![stream-]+s",
d6e69534 559 c_msg->seq_num, stream);
f42867e2 560 is_valid = false;
3230ee6b 561 goto end;
3230ee6b 562 }
3230ee6b 563
f42867e2
PP
564 stream_state = create_stream_state(stream);
565 if (!stream_state) {
566 abort();
567 }
fa054faf 568
40f4ba76
PP
569 g_hash_table_insert(iterator->stream_states,
570 (void *) stream, stream_state);
d6e69534 571 stream_state->expected_msg_seq_num++;
f42867e2 572 goto end;
fa054faf
PP
573 }
574
f42867e2
PP
575 if (stream_state->is_ended) {
576 /*
d6e69534 577 * There's a new message which has a reference to a
f42867e2 578 * stream which, from this iterator's point of view, is
d6e69534 579 * ended ("end of stream" message was returned).
f42867e2
PP
580 * This is bad: the API guarantees that it can never
581 * happen.
582 */
583 BT_ASSERT_PRE_MSG("Stream is already ended: %![stream-]+s",
584 stream);
585 is_valid = false;
fa054faf
PP
586 goto end;
587 }
588
d6e69534
PP
589 if (c_msg->seq_num == -1ULL) {
590 msg->seq_num = stream_state->expected_msg_seq_num;
3230ee6b
PP
591 }
592
d6e69534
PP
593 if (c_msg->seq_num != -1ULL &&
594 c_msg->seq_num != stream_state->expected_msg_seq_num) {
595 BT_ASSERT_PRE_MSG("Unexpected message sequence number: "
f42867e2
PP
596 "seq-num=%" PRIu64 ", "
597 "expected-seq-num=%" PRIu64 ", %![stream-]+s",
d6e69534 598 c_msg->seq_num, stream_state->expected_msg_seq_num,
f42867e2
PP
599 stream);
600 is_valid = false;
fa054faf
PP
601 goto end;
602 }
603
d6e69534
PP
604 switch (c_msg->type) {
605 case BT_MESSAGE_TYPE_STREAM_BEGINNING:
606 BT_ASSERT_PRE_MSG("Unexpected BT_MESSAGE_TYPE_STREAM_BEGINNING "
607 "message at this point: msg-seq-num=%" PRIu64 ", "
608 "%![stream-]+s", c_msg->seq_num, stream);
f42867e2
PP
609 is_valid = false;
610 goto end;
d6e69534 611 case BT_MESSAGE_TYPE_STREAM_END:
f42867e2 612 if (stream_state->cur_packet) {
d6e69534
PP
613 BT_ASSERT_PRE_MSG("Unexpected BT_MESSAGE_TYPE_STREAM_END "
614 "message: missing a "
615 "BT_MESSAGE_TYPE_PACKET_END message "
616 "prior to this message: "
617 "msg-seq-num=%" PRIu64 ", "
618 "%![stream-]+s", c_msg->seq_num, stream);
f42867e2
PP
619 is_valid = false;
620 goto end;
621 }
d6e69534 622 stream_state->expected_msg_seq_num++;
f42867e2
PP
623 stream_state->is_ended = true;
624 goto end;
d6e69534 625 case BT_MESSAGE_TYPE_PACKET_BEGINNING:
f42867e2 626 if (stream_state->cur_packet) {
d6e69534
PP
627 BT_ASSERT_PRE_MSG("Unexpected BT_MESSAGE_TYPE_PACKET_BEGINNING "
628 "message at this point: missing a "
629 "BT_MESSAGE_TYPE_PACKET_END message "
630 "prior to this message: "
631 "msg-seq-num=%" PRIu64 ", %![stream-]+s, "
632 "%![packet-]+a", c_msg->seq_num, stream,
f42867e2
PP
633 packet);
634 is_valid = false;
635 goto end;
636 }
d6e69534 637 stream_state->expected_msg_seq_num++;
398454ed
PP
638 stream_state->cur_packet = packet;
639 bt_object_get_no_null_check(stream_state->cur_packet);
f42867e2 640 goto end;
d6e69534 641 case BT_MESSAGE_TYPE_PACKET_END:
f42867e2 642 if (!stream_state->cur_packet) {
d6e69534
PP
643 BT_ASSERT_PRE_MSG("Unexpected BT_MESSAGE_TYPE_PACKET_END "
644 "message at this point: missing a "
645 "BT_MESSAGE_TYPE_PACKET_BEGINNING message "
646 "prior to this message: "
647 "msg-seq-num=%" PRIu64 ", %![stream-]+s, "
648 "%![packet-]+a", c_msg->seq_num, stream,
f42867e2
PP
649 packet);
650 is_valid = false;
651 goto end;
652 }
d6e69534 653 stream_state->expected_msg_seq_num++;
65300d60 654 BT_OBJECT_PUT_REF_AND_RESET(stream_state->cur_packet);
f42867e2 655 goto end;
d6e69534 656 case BT_MESSAGE_TYPE_EVENT:
f42867e2
PP
657 if (packet != stream_state->cur_packet) {
658 BT_ASSERT_PRE_MSG("Unexpected packet for "
d6e69534
PP
659 "BT_MESSAGE_TYPE_EVENT message: "
660 "msg-seq-num=%" PRIu64 ", %![stream-]+s, "
661 "%![msg-packet-]+a, %![expected-packet-]+a",
662 c_msg->seq_num, stream,
f42867e2
PP
663 stream_state->cur_packet, packet);
664 is_valid = false;
665 goto end;
666 }
d6e69534 667 stream_state->expected_msg_seq_num++;
f42867e2
PP
668 goto end;
669 default:
670 break;
3230ee6b
PP
671 }
672
3230ee6b 673end:
f42867e2 674 return is_valid;
3230ee6b
PP
675}
676
d4393e08
PP
677BT_ASSERT_PRE_FUNC
678static inline
d6e69534
PP
679bool validate_messages(
680 struct bt_self_component_port_input_message_iterator *iterator,
d4393e08
PP
681 uint64_t count)
682{
683 bool ret = true;
d6e69534
PP
684 bt_message_array_const msgs =
685 (void *) iterator->base.msgs->pdata;
d4393e08
PP
686 uint64_t i;
687
688 for (i = 0; i < count; i++) {
d6e69534 689 ret = validate_message(iterator, msgs[i]);
d4393e08
PP
690 if (!ret) {
691 break;
692 }
693 }
694
695 return ret;
696}
697
f42867e2 698BT_ASSERT_PRE_FUNC
d6e69534
PP
699static inline bool self_comp_port_input_msg_iter_can_end(
700 struct bt_self_component_port_input_message_iterator *iterator)
3230ee6b 701{
f42867e2
PP
702 GHashTableIter iter;
703 gpointer stream_key, state_value;
704 bool ret = true;
3230ee6b 705
f42867e2
PP
706 /*
707 * Verify that this iterator received a
d6e69534 708 * BT_MESSAGE_TYPE_STREAM_END message for each stream
f42867e2
PP
709 * which has a state.
710 */
3230ee6b 711
f42867e2 712 g_hash_table_iter_init(&iter, iterator->stream_states);
3230ee6b 713
f42867e2
PP
714 while (g_hash_table_iter_next(&iter, &stream_key, &state_value)) {
715 struct stream_state *stream_state = (void *) state_value;
3230ee6b 716
f42867e2
PP
717 BT_ASSERT(stream_state);
718 BT_ASSERT(stream_key);
fa054faf 719
f42867e2 720 if (!stream_state->is_ended) {
d6e69534 721 BT_ASSERT_PRE_MSG("Ending message iterator, "
f42867e2
PP
722 "but stream is not ended: "
723 "%![stream-]s", stream_key);
724 ret = false;
725 goto end;
726 }
3230ee6b
PP
727 }
728
3230ee6b 729end:
3230ee6b
PP
730 return ret;
731}
732
d6e69534
PP
733enum bt_message_iterator_status
734bt_self_component_port_input_message_iterator_next(
735 struct bt_self_component_port_input_message_iterator *iterator,
736 bt_message_array_const *msgs, uint64_t *user_count)
3230ee6b 737{
d6e69534
PP
738 typedef enum bt_self_message_iterator_status (*method_t)(
739 void *, bt_message_array_const, uint64_t, uint64_t *);
d94d92ac
PP
740
741 method_t method = NULL;
742 struct bt_component_class *comp_cls;
d6e69534 743 int status = BT_MESSAGE_ITERATOR_STATUS_OK;
d94d92ac 744
d6e69534
PP
745 BT_ASSERT_PRE_NON_NULL(iterator, "Message iterator");
746 BT_ASSERT_PRE_NON_NULL(msgs, "Message array (output)");
747 BT_ASSERT_PRE_NON_NULL(user_count, "Message count (output)");
f42867e2 748 BT_ASSERT_PRE(iterator->state ==
d6e69534
PP
749 BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_STATE_ACTIVE,
750 "Message iterator's \"next\" called, but "
f42867e2
PP
751 "iterator is in the wrong state: %!+i", iterator);
752 BT_ASSERT(iterator->upstream_component);
753 BT_ASSERT(iterator->upstream_component->class);
d94d92ac 754 BT_LIB_LOGD("Getting next self component input port "
d6e69534 755 "message iterator's messages: %!+i", iterator);
d94d92ac 756 comp_cls = iterator->upstream_component->class;
d3eb6e8f 757
3230ee6b 758 /* Pick the appropriate "next" method */
d94d92ac 759 switch (comp_cls->type) {
d3eb6e8f
PP
760 case BT_COMPONENT_CLASS_TYPE_SOURCE:
761 {
d94d92ac
PP
762 struct bt_component_class_source *src_comp_cls =
763 (void *) comp_cls;
d3eb6e8f 764
d6e69534 765 method = (method_t) src_comp_cls->methods.msg_iter_next;
d3eb6e8f
PP
766 break;
767 }
768 case BT_COMPONENT_CLASS_TYPE_FILTER:
769 {
d94d92ac
PP
770 struct bt_component_class_filter *flt_comp_cls =
771 (void *) comp_cls;
d3eb6e8f 772
d6e69534 773 method = (method_t) flt_comp_cls->methods.msg_iter_next;
d3eb6e8f
PP
774 break;
775 }
776 default:
0fbb9a9f 777 abort();
d3eb6e8f
PP
778 }
779
3230ee6b 780 /*
d6e69534 781 * Call the user's "next" method to get the next messages
fa054faf 782 * and status.
3230ee6b 783 */
d94d92ac 784 BT_ASSERT(method);
f42867e2 785 BT_LOGD_STR("Calling user's \"next\" method.");
d0fea130 786 status = method(iterator, (void *) iterator->base.msgs->pdata,
d6e69534 787 MSG_BATCH_SIZE, user_count);
f42867e2 788 BT_LOGD("User method returned: status=%s",
d6e69534 789 bt_message_iterator_status_string(status));
d4393e08 790 if (status < 0) {
f42867e2 791 BT_LOGW_STR("User method failed.");
f42867e2
PP
792 goto end;
793 }
3230ee6b 794
d0fea130
PP
795#ifdef BT_DEV_MODE
796 /*
797 * There is no way that this iterator could have been finalized
798 * during its "next" method, as the only way to do this is to
799 * put the last iterator's reference, and this can only be done
800 * by its downstream owner.
801 */
802 BT_ASSERT(iterator->state ==
803 BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_STATE_ACTIVE);
804#endif
8cf27cc5 805
d4393e08 806 switch (status) {
d6e69534
PP
807 case BT_MESSAGE_ITERATOR_STATUS_OK:
808 BT_ASSERT_PRE(validate_messages(iterator, *user_count),
809 "Messages are invalid at this point: "
810 "%![msg-iter-]+i, count=%" PRIu64,
d4393e08 811 iterator, *user_count);
d6e69534 812 *msgs = (void *) iterator->base.msgs->pdata;
d4393e08 813 break;
d6e69534 814 case BT_MESSAGE_ITERATOR_STATUS_AGAIN:
d4393e08 815 goto end;
d6e69534
PP
816 case BT_MESSAGE_ITERATOR_STATUS_END:
817 BT_ASSERT_PRE(self_comp_port_input_msg_iter_can_end(iterator),
818 "Message iterator cannot end at this point: "
f42867e2 819 "%!+i", iterator);
d0fea130
PP
820 set_self_comp_port_input_msg_iterator_state(iterator,
821 BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_STATE_ENDED);
f42867e2 822 goto end;
f42867e2
PP
823 default:
824 /* Unknown non-error status */
825 abort();
41a2b7ae
PP
826 }
827
828end:
3230ee6b
PP
829 return status;
830}
831
d0fea130 832enum bt_message_iterator_status bt_port_output_message_iterator_next(
d6e69534
PP
833 struct bt_port_output_message_iterator *iterator,
834 bt_message_array_const *msgs_to_user,
d4393e08 835 uint64_t *count_to_user)
3230ee6b 836{
d6e69534 837 enum bt_message_iterator_status status;
07245ac2 838 enum bt_graph_status graph_status;
3230ee6b 839
d6e69534
PP
840 BT_ASSERT_PRE_NON_NULL(iterator, "Message iterator");
841 BT_ASSERT_PRE_NON_NULL(msgs_to_user, "Message array (output)");
842 BT_ASSERT_PRE_NON_NULL(count_to_user, "Message count (output)");
843 BT_LIB_LOGD("Getting next output port message iterator's messages: "
07245ac2 844 "%!+i", iterator);
d4393e08 845
d94d92ac
PP
846 graph_status = bt_graph_consume_sink_no_check(iterator->graph,
847 iterator->colander);
07245ac2
PP
848 switch (graph_status) {
849 case BT_GRAPH_STATUS_CANCELED:
07245ac2 850 case BT_GRAPH_STATUS_AGAIN:
07245ac2 851 case BT_GRAPH_STATUS_END:
07245ac2 852 case BT_GRAPH_STATUS_NOMEM:
d94d92ac 853 status = (int) graph_status;
07245ac2
PP
854 break;
855 case BT_GRAPH_STATUS_OK:
d6e69534 856 status = BT_MESSAGE_ITERATOR_STATUS_OK;
d4393e08
PP
857
858 /*
d6e69534 859 * On success, the colander sink moves the messages
d4393e08 860 * to this iterator's array and sets this iterator's
d6e69534 861 * message count: move them to the user.
d4393e08 862 */
d6e69534 863 *msgs_to_user = (void *) iterator->base.msgs->pdata;
d94d92ac 864 *count_to_user = iterator->count;
90157d89 865 break;
90157d89 866 default:
07245ac2 867 /* Other errors */
d6e69534 868 status = BT_MESSAGE_ITERATOR_STATUS_ERROR;
90157d89 869 }
3230ee6b 870
3230ee6b 871 return status;
53d45b87
JG
872}
873
d6e69534
PP
874struct bt_component *bt_self_component_port_input_message_iterator_borrow_component(
875 struct bt_self_component_port_input_message_iterator *iterator)
d94d92ac 876{
d6e69534 877 BT_ASSERT_PRE_NON_NULL(iterator, "Message iterator");
d94d92ac
PP
878 return iterator->upstream_component;
879}
880
d6e69534
PP
881struct bt_self_component *bt_self_message_iterator_borrow_component(
882 struct bt_self_message_iterator *self_iterator)
413bc2c4 883{
d6e69534 884 struct bt_self_component_port_input_message_iterator *iterator =
d94d92ac 885 (void *) self_iterator;
90157d89 886
d6e69534 887 BT_ASSERT_PRE_NON_NULL(iterator, "Message iterator");
d94d92ac 888 return (void *) iterator->upstream_component;
413bc2c4
JG
889}
890
d6e69534
PP
891struct bt_self_port_output *bt_self_message_iterator_borrow_port(
892 struct bt_self_message_iterator *self_iterator)
91457551 893{
d6e69534 894 struct bt_self_component_port_input_message_iterator *iterator =
d94d92ac
PP
895 (void *) self_iterator;
896
d6e69534 897 BT_ASSERT_PRE_NON_NULL(iterator, "Message iterator");
d94d92ac 898 return (void *) iterator->upstream_port;
91457551 899}
8ed535b5
PP
900
901static
d6e69534 902void bt_port_output_message_iterator_destroy(struct bt_object *obj)
8ed535b5 903{
d6e69534 904 struct bt_port_output_message_iterator *iterator = (void *) obj;
8ed535b5 905
d6e69534 906 BT_LIB_LOGD("Destroying output port message iterator object: %!+i",
8ed535b5
PP
907 iterator);
908 BT_LOGD_STR("Putting graph.");
d94d92ac 909 BT_OBJECT_PUT_REF_AND_RESET(iterator->graph);
8ed535b5 910 BT_LOGD_STR("Putting colander sink component.");
d94d92ac 911 BT_OBJECT_PUT_REF_AND_RESET(iterator->colander);
d6e69534 912 destroy_base_message_iterator(obj);
8ed535b5
PP
913}
914
d6e69534
PP
915struct bt_port_output_message_iterator *
916bt_port_output_message_iterator_create(
0d72b8c3
PP
917 struct bt_graph *graph,
918 const struct bt_port_output *output_port)
8ed535b5 919{
d6e69534 920 struct bt_port_output_message_iterator *iterator = NULL;
d94d92ac 921 struct bt_component_class_sink *colander_comp_cls = NULL;
8ed535b5 922 struct bt_component *output_port_comp = NULL;
d94d92ac 923 struct bt_component_sink *colander_comp;
8ed535b5 924 enum bt_graph_status graph_status;
d94d92ac 925 struct bt_port_input *colander_in_port = NULL;
8ed535b5 926 struct bt_component_class_sink_colander_data colander_data;
d4393e08 927 int ret;
8ed535b5 928
d94d92ac 929 BT_ASSERT_PRE_NON_NULL(graph, "Graph");
f42867e2 930 BT_ASSERT_PRE_NON_NULL(output_port, "Output port");
0d72b8c3
PP
931 output_port_comp = bt_port_borrow_component_inline(
932 (const void *) output_port);
f42867e2
PP
933 BT_ASSERT_PRE(output_port_comp,
934 "Output port has no component: %!+p", output_port);
d94d92ac
PP
935 BT_ASSERT_PRE(bt_component_borrow_graph(output_port_comp) ==
936 (void *) graph,
937 "Output port is not part of graph: %![graph-]+g, %![port-]+p",
938 graph, output_port);
8ed535b5 939
d6e69534
PP
940 /* Create message iterator */
941 BT_LIB_LOGD("Creating message iterator on output port: "
d94d92ac 942 "%![port-]+p, %![comp-]+c", output_port, output_port_comp);
d6e69534 943 iterator = g_new0(struct bt_port_output_message_iterator, 1);
8ed535b5 944 if (!iterator) {
d6e69534 945 BT_LOGE_STR("Failed to allocate one output port message iterator.");
8ed535b5
PP
946 goto error;
947 }
948
d6e69534
PP
949 ret = init_message_iterator((void *) iterator,
950 BT_MESSAGE_ITERATOR_TYPE_PORT_OUTPUT,
951 bt_port_output_message_iterator_destroy);
d4393e08 952 if (ret) {
d6e69534 953 /* init_message_iterator() logs errors */
65300d60 954 BT_OBJECT_PUT_REF_AND_RESET(iterator);
d4393e08
PP
955 goto end;
956 }
8ed535b5
PP
957
958 /* Create colander component */
959 colander_comp_cls = bt_component_class_sink_colander_get();
960 if (!colander_comp_cls) {
961 BT_LOGW("Cannot get colander sink component class.");
962 goto error;
963 }
964
398454ed
PP
965 iterator->graph = graph;
966 bt_object_get_no_null_check(iterator->graph);
d6e69534 967 colander_data.msgs = (void *) iterator->base.msgs->pdata;
d4393e08 968 colander_data.count_addr = &iterator->count;
5fd91d88
PP
969
970 /* Hope that nobody uses this very unique name */
d94d92ac 971 graph_status =
0d72b8c3 972 bt_graph_add_sink_component_with_init_method_data(
5fd91d88
PP
973 (void *) graph, colander_comp_cls,
974 "colander-36ac3409-b1a8-4d60-ab1f-4fdf341a8fb1",
0d72b8c3 975 NULL, &colander_data, (void *) &iterator->colander);
8ed535b5 976 if (graph_status != BT_GRAPH_STATUS_OK) {
d94d92ac
PP
977 BT_LIB_LOGW("Cannot add colander sink component to graph: "
978 "%1[graph-]+g, status=%s", graph,
8ed535b5
PP
979 bt_graph_status_string(graph_status));
980 goto error;
981 }
982
983 /*
984 * Connect provided output port to the colander component's
985 * input port.
986 */
0d72b8c3
PP
987 colander_in_port =
988 (void *) bt_component_sink_borrow_input_port_by_index_const(
989 (void *) iterator->colander, 0);
f6ccaed9 990 BT_ASSERT(colander_in_port);
0d72b8c3 991 graph_status = bt_graph_connect_ports(graph,
8ed535b5
PP
992 output_port, colander_in_port, NULL);
993 if (graph_status != BT_GRAPH_STATUS_OK) {
d94d92ac
PP
994 BT_LIB_LOGW("Cannot add colander sink component to graph: "
995 "%![graph-]+g, %![comp-]+c, status=%s", graph,
996 iterator->colander,
8ed535b5
PP
997 bt_graph_status_string(graph_status));
998 goto error;
999 }
1000
1001 /*
1002 * At this point everything went fine. Make the graph
d6e69534 1003 * nonconsumable forever so that only this message iterator
8ed535b5 1004 * can consume (thanks to bt_graph_consume_sink_no_check()).
d6e69534
PP
1005 * This avoids leaking the message created by the colander
1006 * sink and moved to the message iterator's message
07245ac2 1007 * member.
8ed535b5 1008 */
d94d92ac 1009 bt_graph_set_can_consume(iterator->graph, false);
8ed535b5
PP
1010 goto end;
1011
1012error:
1013 if (iterator && iterator->graph && iterator->colander) {
1014 int ret;
1015
1016 /* Remove created colander component from graph if any */
1017 colander_comp = iterator->colander;
65300d60 1018 BT_OBJECT_PUT_REF_AND_RESET(iterator->colander);
8ed535b5
PP
1019
1020 /*
1021 * At this point the colander component's reference
1022 * count is 0 because iterator->colander was the only
1023 * owner. We also know that it is not connected because
1024 * this is the last operation before this function
1025 * succeeds.
1026 *
1027 * Since we honor the preconditions here,
1028 * bt_graph_remove_unconnected_component() always
1029 * succeeds.
1030 */
1031 ret = bt_graph_remove_unconnected_component(iterator->graph,
d94d92ac 1032 (void *) colander_comp);
f6ccaed9 1033 BT_ASSERT(ret == 0);
8ed535b5
PP
1034 }
1035
65300d60 1036 BT_OBJECT_PUT_REF_AND_RESET(iterator);
8ed535b5
PP
1037
1038end:
65300d60 1039 bt_object_put_ref(colander_comp_cls);
8ed535b5
PP
1040 return (void *) iterator;
1041}
c5b9b441 1042
d6e69534
PP
1043void bt_port_output_message_iterator_get_ref(
1044 const struct bt_port_output_message_iterator *iterator)
c5b9b441
PP
1045{
1046 bt_object_get_ref(iterator);
1047}
1048
d6e69534
PP
1049void bt_port_output_message_iterator_put_ref(
1050 const struct bt_port_output_message_iterator *iterator)
c5b9b441
PP
1051{
1052 bt_object_put_ref(iterator);
1053}
1054
d6e69534
PP
1055void bt_self_component_port_input_message_iterator_get_ref(
1056 const struct bt_self_component_port_input_message_iterator *iterator)
c5b9b441
PP
1057{
1058 bt_object_get_ref(iterator);
1059}
1060
d6e69534
PP
1061void bt_self_component_port_input_message_iterator_put_ref(
1062 const struct bt_self_component_port_input_message_iterator *iterator)
c5b9b441
PP
1063{
1064 bt_object_put_ref(iterator);
1065}
This page took 0.099316 seconds and 4 git commands to generate.