Fix: ctf plugin: returning bt_message_iterator_status from src.ctf.fs
[babeltrace.git] / lib / graph / iterator.c
CommitLineData
47e5a032 1/*
f2b0325d 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
b09a5592 24#define BT_LOG_TAG "MSG-ITER"
5af447e5
PP
25#include <babeltrace/lib-logging-internal.h>
26
3d9990ac 27#include <babeltrace/compiler-internal.h>
0f15f666 28#include <babeltrace/trace-ir/field.h>
78cf9df6 29#include <babeltrace/trace-ir/event-const.h>
108b91d0 30#include <babeltrace/trace-ir/event-internal.h>
78cf9df6 31#include <babeltrace/trace-ir/packet-const.h>
108b91d0
PP
32#include <babeltrace/trace-ir/packet-internal.h>
33#include <babeltrace/trace-ir/stream-internal.h>
7b53201c 34#include <babeltrace/graph/connection-const.h>
bd14d768 35#include <babeltrace/graph/connection-internal.h>
7b53201c 36#include <babeltrace/graph/component-const.h>
9e550e5f 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>
c3ac0193 40#include <babeltrace/graph/component-class-sink-colander-internal.h>
7b53201c 41#include <babeltrace/graph/component-sink-const.h>
b09a5592
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>
7b53201c
PP
54#include <babeltrace/graph/port-const.h>
55#include <babeltrace/graph/graph.h>
56#include <babeltrace/graph/graph-const.h>
c3ac0193 57#include <babeltrace/graph/graph-internal.h>
c55a9f58 58#include <babeltrace/types.h>
8b45963b 59#include <babeltrace/assert-internal.h>
6ff151ad 60#include <babeltrace/assert-pre-internal.h>
fa054faf 61#include <stdint.h>
b04a393b 62#include <inttypes.h>
0fbb9a9f 63#include <stdlib.h>
3230ee6b 64
3fd7b79d
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 */
b09a5592 69#define MSG_BATCH_SIZE 15
3fd7b79d 70
3230ee6b 71struct stream_state {
78cf9df6
PP
72 const struct bt_stream *stream; /* owned by this */
73 const struct bt_packet *cur_packet; /* owned by this */
b09a5592 74 uint64_t expected_msg_seq_num;
c55a9f58 75 bt_bool is_ended;
3230ee6b
PP
76};
77
22e3b27d 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.");
834e9996 88 BT_OBJECT_PUT_REF_AND_RESET(stream_state->cur_packet);
5af447e5 89 BT_LOGV_STR("Putting stream state's stream.");
834e9996 90 BT_OBJECT_PUT_REF_AND_RESET(stream_state->stream);
3230ee6b
PP
91 g_free(stream_state);
92}
93
22e3b27d 94BT_ASSERT_PRE_FUNC
3230ee6b 95static
78cf9df6 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 /*
6ff151ad 106 * We keep a reference to the stream until we know it's ended.
3230ee6b 107 */
4b70020d
PP
108 stream_state->stream = stream;
109 bt_object_get_no_null_check(stream_state->stream);
834e9996 110 BT_LIB_LOGV("Created stream state: %![stream-]+s, "
5af447e5 111 "stream-state-addr=%p",
834e9996 112 stream, stream_state);
3230ee6b
PP
113
114end:
115 return stream_state;
116}
47e5a032 117
904860cb
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
c3ac0193 136static
b09a5592 137void destroy_base_message_iterator(struct bt_object *obj)
c3ac0193 138{
b09a5592 139 struct bt_message_iterator *iterator = (void *) obj;
3fd7b79d
PP
140
141 BT_ASSERT(iterator);
142
b09a5592
PP
143 if (iterator->msgs) {
144 g_ptr_array_free(iterator->msgs, TRUE);
145 iterator->msgs = NULL;
3fd7b79d
PP
146 }
147
148 g_free(iterator);
c3ac0193
PP
149}
150
47e5a032 151static
b09a5592 152void bt_self_component_port_input_message_iterator_destroy(struct bt_object *obj)
47e5a032 153{
b09a5592 154 struct bt_self_component_port_input_message_iterator *iterator;
8738a040 155
8b45963b 156 BT_ASSERT(obj);
d3eb6e8f 157
bd14d768 158 /*
b09a5592 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
b09a5592 162 * message iterator's finalization function does
834e9996
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 */
1d7bf349 169 obj->ref_count++;
94a96686 170 iterator = (void *) obj;
b09a5592 171 BT_LIB_LOGD("Destroying self component input port message iterator object: "
834e9996 172 "%!+i", iterator);
904860cb 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
b09a5592 180 * message iterator object.
3230ee6b 181 */
3230ee6b 182 g_hash_table_destroy(iterator->stream_states);
834e9996 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);
834e9996 193 iterator->connection = NULL;
bd14d768
PP
194 }
195
b09a5592 196 destroy_base_message_iterator(obj);
47e5a032
JG
197}
198
bd14d768 199BT_HIDDEN
904860cb 200void bt_self_component_port_input_message_iterator_try_finalize(
b09a5592 201 struct bt_self_component_port_input_message_iterator *iterator)
bd14d768 202{
834e9996
PP
203 typedef void (*method_t)(void *);
204
bd14d768 205 struct bt_component_class *comp_class = NULL;
834e9996 206 method_t method = NULL;
bd14d768 207
8b45963b 208 BT_ASSERT(iterator);
bd14d768
PP
209
210 switch (iterator->state) {
b09a5592 211 case BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_STATE_NON_INITIALIZED:
dba1e5d8 212 /* Skip user finalization if user initialization failed */
b09a5592 213 BT_LIB_LOGD("Not finalizing non-initialized message iterator: "
834e9996 214 "%!+i", iterator);
904860cb 215 goto end;
b09a5592 216 case BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_STATE_FINALIZED:
bd14d768 217 /* Already finalized */
b09a5592 218 BT_LIB_LOGD("Not finalizing message iterator: already finalized: "
834e9996 219 "%!+i", iterator);
904860cb
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
b09a5592 230 BT_LIB_LOGD("Finalizing message iterator: %!+i", iterator);
904860cb
PP
231 set_self_comp_port_input_msg_iterator_state(iterator,
232 BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_STATE_FINALIZING);
8b45963b 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 {
834e9996
PP
240 struct bt_component_class_source *src_comp_cls =
241 (void *) comp_class;
bd14d768 242
b09a5592 243 method = (method_t) src_comp_cls->methods.msg_iter_finalize;
bd14d768
PP
244 break;
245 }
246 case BT_COMPONENT_CLASS_TYPE_FILTER:
247 {
834e9996
PP
248 struct bt_component_class_filter *flt_comp_cls =
249 (void *) comp_class;
bd14d768 250
b09a5592 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
834e9996
PP
259 if (method) {
260 BT_LIB_LOGD("Calling user's finalization method: %!+i",
5af447e5 261 iterator);
834e9996 262 method(iterator);
bd14d768
PP
263 }
264
bd14d768
PP
265 iterator->upstream_component = NULL;
266 iterator->upstream_port = NULL;
904860cb
PP
267 set_self_comp_port_input_msg_iterator_state(iterator,
268 BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_STATE_FINALIZED);
b09a5592 269 BT_LIB_LOGD("Finalized message iterator: %!+i", iterator);
904860cb
PP
270
271end:
272 return;
bd14d768
PP
273}
274
275BT_HIDDEN
b09a5592
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{
8b45963b 280 BT_ASSERT(iterator);
bd14d768 281 iterator->connection = connection;
b09a5592 282 BT_LIB_LOGV("Set message iterator's connection: "
834e9996 283 "%![iter-]+i, %![conn-]+x", iterator, connection);
bd14d768
PP
284}
285
fe7265b5 286static
b09a5592
PP
287int init_message_iterator(struct bt_message_iterator *iterator,
288 enum bt_message_iterator_type type,
fe7265b5
PP
289 bt_object_release_func destroy)
290{
3fd7b79d
PP
291 int ret = 0;
292
1d7bf349 293 bt_object_init_shared(&iterator->base, destroy);
fe7265b5 294 iterator->type = type;
b09a5592
PP
295 iterator->msgs = g_ptr_array_new();
296 if (!iterator->msgs) {
3fd7b79d
PP
297 BT_LOGE_STR("Failed to allocate a GPtrArray.");
298 ret = -1;
299 goto end;
300 }
301
b09a5592 302 g_ptr_array_set_size(iterator->msgs, MSG_BATCH_SIZE);
3fd7b79d
PP
303
304end:
305 return ret;
fe7265b5
PP
306}
307
834e9996 308static
b09a5592
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,
834e9996 312 struct bt_port *upstream_port)
47e5a032 313{
3fd7b79d 314 int ret;
b09a5592 315 struct bt_self_component_port_input_message_iterator *iterator = NULL;
47e5a032 316
8b45963b
PP
317 BT_ASSERT(upstream_comp);
318 BT_ASSERT(upstream_port);
8b45963b 319 BT_ASSERT(bt_port_is_connected(upstream_port));
b09a5592 320 BT_LIB_LOGD("Creating initial message iterator on self component input port: "
834e9996
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(
b09a5592 327 struct bt_self_component_port_input_message_iterator, 1);
47e5a032 328 if (!iterator) {
834e9996 329 BT_LOGE_STR("Failed to allocate one self component input port "
b09a5592 330 "message iterator.");
73d5c1ad 331 goto end;
47e5a032
JG
332 }
333
b09a5592
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);
3fd7b79d 337 if (ret) {
b09a5592 338 /* init_message_iterator() logs errors */
834e9996 339 BT_OBJECT_PUT_REF_AND_RESET(iterator);
3fd7b79d
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.");
834e9996 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;
834e9996 353 iterator->connection = iterator->upstream_port->connection;
f7c3ac09 354 iterator->graph = bt_component_borrow_graph(upstream_comp);
904860cb
PP
355 set_self_comp_port_input_msg_iterator_state(iterator,
356 BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_STATE_NON_INITIALIZED);
b09a5592 357 BT_LIB_LOGD("Created initial message iterator on self component input port: "
834e9996
PP
358 "%![up-port-]+p, %![up-comp-]+c, %![iter-]+i",
359 upstream_port, upstream_comp, iterator);
3230ee6b 360
47e5a032 361end:
834e9996 362 return iterator;
47e5a032
JG
363}
364
b09a5592
PP
365struct bt_self_component_port_input_message_iterator *
366bt_self_component_port_input_message_iterator_create(
834e9996 367 struct bt_self_component_port_input *self_port)
ea8d3e58 368{
b09a5592 369 typedef enum bt_self_message_iterator_status (*init_method_t)(
834e9996
PP
370 void *, void *, void *);
371
372 init_method_t init_method = NULL;
b09a5592 373 struct bt_self_component_port_input_message_iterator *iterator =
834e9996
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");
7b53201c 382 comp = bt_port_borrow_component_inline(port);
834e9996
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);
7b53201c 393 upstream_comp = bt_port_borrow_component_inline(upstream_port);
834e9996
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);
b09a5592 400 iterator = bt_self_component_port_input_message_iterator_create_initial(
834e9996
PP
401 upstream_comp, upstream_port);
402 if (!iterator) {
403 BT_LOGW_STR("Cannot create self component input port "
b09a5592 404 "message iterator.");
834e9996
PP
405 goto end;
406 }
890882ef 407
834e9996
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 =
b09a5592 415 (init_method_t) src_comp_cls->methods.msg_iter_init;
834e9996
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 =
b09a5592 424 (init_method_t) flt_comp_cls->methods.msg_iter_init;
834e9996
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",
b09a5592
PP
439 bt_message_iterator_status_string(iter_status));
440 if (iter_status != BT_MESSAGE_ITERATOR_STATUS_OK) {
834e9996 441 BT_LOGW_STR("Initialization method failed.");
904860cb 442 BT_OBJECT_PUT_REF_AND_RESET(iterator);
834e9996
PP
443 goto end;
444 }
445 }
446
904860cb
PP
447 set_self_comp_port_input_msg_iterator_state(iterator,
448 BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_STATE_ACTIVE);
834e9996 449 g_ptr_array_add(port->connection->iterators, iterator);
b09a5592 450 BT_LIB_LOGD("Created message iterator on self component input port: "
834e9996
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
b09a5592
PP
458void *bt_self_message_iterator_get_data(
459 const struct bt_self_message_iterator *self_iterator)
ea8d3e58 460{
b09a5592 461 struct bt_self_component_port_input_message_iterator *iterator =
834e9996 462 (void *) self_iterator;
ea8d3e58 463
b09a5592 464 BT_ASSERT_PRE_NON_NULL(iterator, "Message iterator");
834e9996 465 return iterator->user_data;
8738a040 466}
413bc2c4 467
b09a5592
PP
468void bt_self_message_iterator_set_data(
469 struct bt_self_message_iterator *self_iterator, void *data)
f7c3ac09 470{
b09a5592 471 struct bt_self_component_port_input_message_iterator *iterator =
834e9996 472 (void *) self_iterator;
f7c3ac09 473
b09a5592 474 BT_ASSERT_PRE_NON_NULL(iterator, "Message iterator");
834e9996 475 iterator->user_data = data;
b09a5592 476 BT_LIB_LOGV("Set message iterator's user data: "
834e9996 477 "%!+i, user-data-addr=%p", iterator, data);
f7c3ac09
PP
478}
479
6ff151ad
PP
480BT_ASSERT_PRE_FUNC
481static inline
b09a5592 482void bt_message_borrow_packet_stream(const struct bt_message *msg,
78cf9df6
PP
483 const struct bt_stream **stream,
484 const struct bt_packet **packet)
fa054faf 485{
b09a5592 486 BT_ASSERT(msg);
fa054faf 487
b09a5592
PP
488 switch (msg->type) {
489 case BT_MESSAGE_TYPE_EVENT:
78cf9df6 490 *packet = bt_event_borrow_packet_const(
b09a5592 491 bt_message_event_borrow_event_const(msg));
78cf9df6 492 *stream = bt_packet_borrow_stream_const(*packet);
fa054faf 493 break;
b09a5592
PP
494 case BT_MESSAGE_TYPE_STREAM_BEGINNING:
495 *stream = bt_message_stream_beginning_borrow_stream_const(msg);
fa054faf 496 break;
b09a5592
PP
497 case BT_MESSAGE_TYPE_STREAM_END:
498 *stream = bt_message_stream_end_borrow_stream_const(msg);
fa054faf 499 break;
b09a5592
PP
500 case BT_MESSAGE_TYPE_PACKET_BEGINNING:
501 *packet = bt_message_packet_beginning_borrow_packet_const(msg);
78cf9df6 502 *stream = bt_packet_borrow_stream_const(*packet);
fa054faf 503 break;
b09a5592
PP
504 case BT_MESSAGE_TYPE_PACKET_END:
505 *packet = bt_message_packet_end_borrow_packet_const(msg);
78cf9df6 506 *stream = bt_packet_borrow_stream_const(*packet);
b04a393b 507 break;
fa054faf 508 default:
6ff151ad 509 break;
fa054faf 510 }
fa054faf
PP
511}
512
6ff151ad
PP
513BT_ASSERT_PRE_FUNC
514static inline
b09a5592
PP
515bool validate_message(
516 struct bt_self_component_port_input_message_iterator *iterator,
517 const struct bt_message *c_msg)
3230ee6b 518{
6ff151ad 519 bool is_valid = true;
3230ee6b 520 struct stream_state *stream_state;
78cf9df6
PP
521 const struct bt_stream *stream = NULL;
522 const struct bt_packet *packet = NULL;
b09a5592 523 struct bt_message *msg = (void *) c_msg;
6ff151ad 524
b09a5592
PP
525 BT_ASSERT(msg);
526 bt_message_borrow_packet_stream(c_msg, &stream, &packet);
6ff151ad
PP
527
528 if (!stream) {
b09a5592 529 /* we don't care about messages not attached to streams */
6ff151ad
PP
530 goto end;
531 }
3230ee6b 532
6ff151ad
PP
533 stream_state = g_hash_table_lookup(iterator->stream_states, stream);
534 if (!stream_state) {
3230ee6b 535 /*
b09a5592
PP
536 * No stream state for this stream: this message
537 * MUST be a BT_MESSAGE_TYPE_STREAM_BEGINNING message
6ff151ad 538 * and its sequence number must be 0.
3230ee6b 539 */
b09a5592
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: "
6ff151ad
PP
544 "%![stream-]+s", stream);
545 is_valid = false;
3230ee6b
PP
546 goto end;
547 }
548
b09a5592
PP
549 if (c_msg->seq_num == -1ULL) {
550 msg->seq_num = 0;
3230ee6b
PP
551 }
552
b09a5592
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 "
6ff151ad
PP
557 "stream, expecting sequence number 0: "
558 "seq-num=%" PRIu64 ", %![stream-]+s",
b09a5592 559 c_msg->seq_num, stream);
6ff151ad 560 is_valid = false;
3230ee6b 561 goto end;
3230ee6b 562 }
3230ee6b 563
6ff151ad
PP
564 stream_state = create_stream_state(stream);
565 if (!stream_state) {
566 abort();
567 }
fa054faf 568
78cf9df6
PP
569 g_hash_table_insert(iterator->stream_states,
570 (void *) stream, stream_state);
b09a5592 571 stream_state->expected_msg_seq_num++;
6ff151ad 572 goto end;
fa054faf
PP
573 }
574
6ff151ad
PP
575 if (stream_state->is_ended) {
576 /*
b09a5592 577 * There's a new message which has a reference to a
6ff151ad 578 * stream which, from this iterator's point of view, is
b09a5592 579 * ended ("end of stream" message was returned).
6ff151ad
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
b09a5592
PP
589 if (c_msg->seq_num == -1ULL) {
590 msg->seq_num = stream_state->expected_msg_seq_num;
3230ee6b
PP
591 }
592
b09a5592
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: "
6ff151ad
PP
596 "seq-num=%" PRIu64 ", "
597 "expected-seq-num=%" PRIu64 ", %![stream-]+s",
b09a5592 598 c_msg->seq_num, stream_state->expected_msg_seq_num,
6ff151ad
PP
599 stream);
600 is_valid = false;
fa054faf
PP
601 goto end;
602 }
603
b09a5592
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);
6ff151ad
PP
609 is_valid = false;
610 goto end;
b09a5592 611 case BT_MESSAGE_TYPE_STREAM_END:
6ff151ad 612 if (stream_state->cur_packet) {
b09a5592
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);
6ff151ad
PP
619 is_valid = false;
620 goto end;
621 }
b09a5592 622 stream_state->expected_msg_seq_num++;
6ff151ad
PP
623 stream_state->is_ended = true;
624 goto end;
b09a5592 625 case BT_MESSAGE_TYPE_PACKET_BEGINNING:
6ff151ad 626 if (stream_state->cur_packet) {
b09a5592
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,
6ff151ad
PP
633 packet);
634 is_valid = false;
635 goto end;
636 }
b09a5592 637 stream_state->expected_msg_seq_num++;
4b70020d
PP
638 stream_state->cur_packet = packet;
639 bt_object_get_no_null_check(stream_state->cur_packet);
6ff151ad 640 goto end;
b09a5592 641 case BT_MESSAGE_TYPE_PACKET_END:
6ff151ad 642 if (!stream_state->cur_packet) {
b09a5592
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,
6ff151ad
PP
649 packet);
650 is_valid = false;
651 goto end;
652 }
b09a5592 653 stream_state->expected_msg_seq_num++;
8138bfe1 654 BT_OBJECT_PUT_REF_AND_RESET(stream_state->cur_packet);
6ff151ad 655 goto end;
b09a5592 656 case BT_MESSAGE_TYPE_EVENT:
6ff151ad
PP
657 if (packet != stream_state->cur_packet) {
658 BT_ASSERT_PRE_MSG("Unexpected packet for "
b09a5592
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,
6ff151ad
PP
663 stream_state->cur_packet, packet);
664 is_valid = false;
665 goto end;
666 }
b09a5592 667 stream_state->expected_msg_seq_num++;
6ff151ad
PP
668 goto end;
669 default:
670 break;
3230ee6b
PP
671 }
672
3230ee6b 673end:
6ff151ad 674 return is_valid;
3230ee6b
PP
675}
676
3fd7b79d
PP
677BT_ASSERT_PRE_FUNC
678static inline
b09a5592
PP
679bool validate_messages(
680 struct bt_self_component_port_input_message_iterator *iterator,
3fd7b79d
PP
681 uint64_t count)
682{
683 bool ret = true;
b09a5592
PP
684 bt_message_array_const msgs =
685 (void *) iterator->base.msgs->pdata;
3fd7b79d
PP
686 uint64_t i;
687
688 for (i = 0; i < count; i++) {
b09a5592 689 ret = validate_message(iterator, msgs[i]);
3fd7b79d
PP
690 if (!ret) {
691 break;
692 }
693 }
694
695 return ret;
696}
697
6ff151ad 698BT_ASSERT_PRE_FUNC
b09a5592
PP
699static inline bool self_comp_port_input_msg_iter_can_end(
700 struct bt_self_component_port_input_message_iterator *iterator)
3230ee6b 701{
6ff151ad
PP
702 GHashTableIter iter;
703 gpointer stream_key, state_value;
704 bool ret = true;
3230ee6b 705
6ff151ad
PP
706 /*
707 * Verify that this iterator received a
b09a5592 708 * BT_MESSAGE_TYPE_STREAM_END message for each stream
6ff151ad
PP
709 * which has a state.
710 */
3230ee6b 711
6ff151ad 712 g_hash_table_iter_init(&iter, iterator->stream_states);
3230ee6b 713
6ff151ad
PP
714 while (g_hash_table_iter_next(&iter, &stream_key, &state_value)) {
715 struct stream_state *stream_state = (void *) state_value;
3230ee6b 716
6ff151ad
PP
717 BT_ASSERT(stream_state);
718 BT_ASSERT(stream_key);
fa054faf 719
6ff151ad 720 if (!stream_state->is_ended) {
b09a5592 721 BT_ASSERT_PRE_MSG("Ending message iterator, "
6ff151ad
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
b09a5592
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{
b09a5592
PP
738 typedef enum bt_self_message_iterator_status (*method_t)(
739 void *, bt_message_array_const, uint64_t, uint64_t *);
834e9996
PP
740
741 method_t method = NULL;
742 struct bt_component_class *comp_cls;
b09a5592 743 int status = BT_MESSAGE_ITERATOR_STATUS_OK;
834e9996 744
b09a5592
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)");
6ff151ad 748 BT_ASSERT_PRE(iterator->state ==
b09a5592
PP
749 BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_STATE_ACTIVE,
750 "Message iterator's \"next\" called, but "
6ff151ad
PP
751 "iterator is in the wrong state: %!+i", iterator);
752 BT_ASSERT(iterator->upstream_component);
753 BT_ASSERT(iterator->upstream_component->class);
834e9996 754 BT_LIB_LOGD("Getting next self component input port "
b09a5592 755 "message iterator's messages: %!+i", iterator);
834e9996 756 comp_cls = iterator->upstream_component->class;
d3eb6e8f 757
3230ee6b 758 /* Pick the appropriate "next" method */
834e9996 759 switch (comp_cls->type) {
d3eb6e8f
PP
760 case BT_COMPONENT_CLASS_TYPE_SOURCE:
761 {
834e9996
PP
762 struct bt_component_class_source *src_comp_cls =
763 (void *) comp_cls;
d3eb6e8f 764
b09a5592 765 method = (method_t) src_comp_cls->methods.msg_iter_next;
d3eb6e8f
PP
766 break;
767 }
768 case BT_COMPONENT_CLASS_TYPE_FILTER:
769 {
834e9996
PP
770 struct bt_component_class_filter *flt_comp_cls =
771 (void *) comp_cls;
d3eb6e8f 772
b09a5592 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 /*
b09a5592 781 * Call the user's "next" method to get the next messages
fa054faf 782 * and status.
3230ee6b 783 */
834e9996 784 BT_ASSERT(method);
6ff151ad 785 BT_LOGD_STR("Calling user's \"next\" method.");
904860cb 786 status = method(iterator, (void *) iterator->base.msgs->pdata,
b09a5592 787 MSG_BATCH_SIZE, user_count);
6ff151ad 788 BT_LOGD("User method returned: status=%s",
b09a5592 789 bt_message_iterator_status_string(status));
3fd7b79d 790 if (status < 0) {
6ff151ad 791 BT_LOGW_STR("User method failed.");
6ff151ad
PP
792 goto end;
793 }
3230ee6b 794
904860cb
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
3fd7b79d 806 switch (status) {
b09a5592
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,
3fd7b79d 811 iterator, *user_count);
b09a5592 812 *msgs = (void *) iterator->base.msgs->pdata;
3fd7b79d 813 break;
b09a5592 814 case BT_MESSAGE_ITERATOR_STATUS_AGAIN:
3fd7b79d 815 goto end;
b09a5592
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: "
6ff151ad 819 "%!+i", iterator);
904860cb
PP
820 set_self_comp_port_input_msg_iterator_state(iterator,
821 BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_STATE_ENDED);
6ff151ad 822 goto end;
6ff151ad
PP
823 default:
824 /* Unknown non-error status */
825 abort();
41a2b7ae
PP
826 }
827
828end:
3230ee6b
PP
829 return status;
830}
831
904860cb 832enum bt_message_iterator_status bt_port_output_message_iterator_next(
b09a5592
PP
833 struct bt_port_output_message_iterator *iterator,
834 bt_message_array_const *msgs_to_user,
3fd7b79d 835 uint64_t *count_to_user)
3230ee6b 836{
b09a5592 837 enum bt_message_iterator_status status;
94a96686 838 enum bt_graph_status graph_status;
3230ee6b 839
b09a5592
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: "
94a96686 844 "%!+i", iterator);
3fd7b79d 845
834e9996
PP
846 graph_status = bt_graph_consume_sink_no_check(iterator->graph,
847 iterator->colander);
94a96686
PP
848 switch (graph_status) {
849 case BT_GRAPH_STATUS_CANCELED:
94a96686 850 case BT_GRAPH_STATUS_AGAIN:
94a96686 851 case BT_GRAPH_STATUS_END:
94a96686 852 case BT_GRAPH_STATUS_NOMEM:
834e9996 853 status = (int) graph_status;
94a96686
PP
854 break;
855 case BT_GRAPH_STATUS_OK:
b09a5592 856 status = BT_MESSAGE_ITERATOR_STATUS_OK;
3fd7b79d
PP
857
858 /*
b09a5592 859 * On success, the colander sink moves the messages
3fd7b79d 860 * to this iterator's array and sets this iterator's
b09a5592 861 * message count: move them to the user.
3fd7b79d 862 */
b09a5592 863 *msgs_to_user = (void *) iterator->base.msgs->pdata;
834e9996 864 *count_to_user = iterator->count;
fe7265b5 865 break;
fe7265b5 866 default:
94a96686 867 /* Other errors */
b09a5592 868 status = BT_MESSAGE_ITERATOR_STATUS_ERROR;
fe7265b5 869 }
3230ee6b 870
3230ee6b 871 return status;
53d45b87
JG
872}
873
b09a5592
PP
874struct bt_component *bt_self_component_port_input_message_iterator_borrow_component(
875 struct bt_self_component_port_input_message_iterator *iterator)
834e9996 876{
b09a5592 877 BT_ASSERT_PRE_NON_NULL(iterator, "Message iterator");
834e9996
PP
878 return iterator->upstream_component;
879}
880
b09a5592
PP
881struct bt_self_component *bt_self_message_iterator_borrow_component(
882 struct bt_self_message_iterator *self_iterator)
413bc2c4 883{
b09a5592 884 struct bt_self_component_port_input_message_iterator *iterator =
834e9996 885 (void *) self_iterator;
fe7265b5 886
b09a5592 887 BT_ASSERT_PRE_NON_NULL(iterator, "Message iterator");
834e9996 888 return (void *) iterator->upstream_component;
413bc2c4
JG
889}
890
b09a5592
PP
891struct bt_self_port_output *bt_self_message_iterator_borrow_port(
892 struct bt_self_message_iterator *self_iterator)
91457551 893{
b09a5592 894 struct bt_self_component_port_input_message_iterator *iterator =
834e9996
PP
895 (void *) self_iterator;
896
b09a5592 897 BT_ASSERT_PRE_NON_NULL(iterator, "Message iterator");
834e9996 898 return (void *) iterator->upstream_port;
91457551 899}
c3ac0193
PP
900
901static
b09a5592 902void bt_port_output_message_iterator_destroy(struct bt_object *obj)
c3ac0193 903{
b09a5592 904 struct bt_port_output_message_iterator *iterator = (void *) obj;
c3ac0193 905
b09a5592 906 BT_LIB_LOGD("Destroying output port message iterator object: %!+i",
c3ac0193
PP
907 iterator);
908 BT_LOGD_STR("Putting graph.");
834e9996 909 BT_OBJECT_PUT_REF_AND_RESET(iterator->graph);
c3ac0193 910 BT_LOGD_STR("Putting colander sink component.");
834e9996 911 BT_OBJECT_PUT_REF_AND_RESET(iterator->colander);
b09a5592 912 destroy_base_message_iterator(obj);
c3ac0193
PP
913}
914
b09a5592
PP
915struct bt_port_output_message_iterator *
916bt_port_output_message_iterator_create(
7b53201c
PP
917 struct bt_graph *graph,
918 const struct bt_port_output *output_port)
c3ac0193 919{
b09a5592 920 struct bt_port_output_message_iterator *iterator = NULL;
834e9996 921 struct bt_component_class_sink *colander_comp_cls = NULL;
c3ac0193 922 struct bt_component *output_port_comp = NULL;
834e9996 923 struct bt_component_sink *colander_comp;
c3ac0193 924 enum bt_graph_status graph_status;
834e9996 925 struct bt_port_input *colander_in_port = NULL;
c3ac0193 926 struct bt_component_class_sink_colander_data colander_data;
3fd7b79d 927 int ret;
c3ac0193 928
834e9996 929 BT_ASSERT_PRE_NON_NULL(graph, "Graph");
6ff151ad 930 BT_ASSERT_PRE_NON_NULL(output_port, "Output port");
7b53201c
PP
931 output_port_comp = bt_port_borrow_component_inline(
932 (const void *) output_port);
6ff151ad
PP
933 BT_ASSERT_PRE(output_port_comp,
934 "Output port has no component: %!+p", output_port);
834e9996
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);
c3ac0193 939
b09a5592
PP
940 /* Create message iterator */
941 BT_LIB_LOGD("Creating message iterator on output port: "
834e9996 942 "%![port-]+p, %![comp-]+c", output_port, output_port_comp);
b09a5592 943 iterator = g_new0(struct bt_port_output_message_iterator, 1);
c3ac0193 944 if (!iterator) {
b09a5592 945 BT_LOGE_STR("Failed to allocate one output port message iterator.");
c3ac0193
PP
946 goto error;
947 }
948
b09a5592
PP
949 ret = init_message_iterator((void *) iterator,
950 BT_MESSAGE_ITERATOR_TYPE_PORT_OUTPUT,
951 bt_port_output_message_iterator_destroy);
3fd7b79d 952 if (ret) {
b09a5592 953 /* init_message_iterator() logs errors */
8138bfe1 954 BT_OBJECT_PUT_REF_AND_RESET(iterator);
3fd7b79d
PP
955 goto end;
956 }
c3ac0193
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
4b70020d
PP
965 iterator->graph = graph;
966 bt_object_get_no_null_check(iterator->graph);
b09a5592 967 colander_data.msgs = (void *) iterator->base.msgs->pdata;
3fd7b79d 968 colander_data.count_addr = &iterator->count;
a9de0e7a
PP
969
970 /* Hope that nobody uses this very unique name */
834e9996 971 graph_status =
7b53201c 972 bt_graph_add_sink_component_with_init_method_data(
a9de0e7a
PP
973 (void *) graph, colander_comp_cls,
974 "colander-36ac3409-b1a8-4d60-ab1f-4fdf341a8fb1",
7b53201c 975 NULL, &colander_data, (void *) &iterator->colander);
c3ac0193 976 if (graph_status != BT_GRAPH_STATUS_OK) {
834e9996
PP
977 BT_LIB_LOGW("Cannot add colander sink component to graph: "
978 "%1[graph-]+g, status=%s", graph,
c3ac0193
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 */
7b53201c
PP
987 colander_in_port =
988 (void *) bt_component_sink_borrow_input_port_by_index_const(
989 (void *) iterator->colander, 0);
8b45963b 990 BT_ASSERT(colander_in_port);
7b53201c 991 graph_status = bt_graph_connect_ports(graph,
c3ac0193
PP
992 output_port, colander_in_port, NULL);
993 if (graph_status != BT_GRAPH_STATUS_OK) {
834e9996
PP
994 BT_LIB_LOGW("Cannot add colander sink component to graph: "
995 "%![graph-]+g, %![comp-]+c, status=%s", graph,
996 iterator->colander,
c3ac0193
PP
997 bt_graph_status_string(graph_status));
998 goto error;
999 }
1000
1001 /*
1002 * At this point everything went fine. Make the graph
b09a5592 1003 * nonconsumable forever so that only this message iterator
c3ac0193 1004 * can consume (thanks to bt_graph_consume_sink_no_check()).
b09a5592
PP
1005 * This avoids leaking the message created by the colander
1006 * sink and moved to the message iterator's message
94a96686 1007 * member.
c3ac0193 1008 */
834e9996 1009 bt_graph_set_can_consume(iterator->graph, false);
c3ac0193
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;
8138bfe1 1018 BT_OBJECT_PUT_REF_AND_RESET(iterator->colander);
c3ac0193
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,
834e9996 1032 (void *) colander_comp);
8b45963b 1033 BT_ASSERT(ret == 0);
c3ac0193
PP
1034 }
1035
8138bfe1 1036 BT_OBJECT_PUT_REF_AND_RESET(iterator);
c3ac0193
PP
1037
1038end:
8138bfe1 1039 bt_object_put_ref(colander_comp_cls);
c3ac0193
PP
1040 return (void *) iterator;
1041}
8c6884d9 1042
b09a5592
PP
1043void bt_port_output_message_iterator_get_ref(
1044 const struct bt_port_output_message_iterator *iterator)
8c6884d9
PP
1045{
1046 bt_object_get_ref(iterator);
1047}
1048
b09a5592
PP
1049void bt_port_output_message_iterator_put_ref(
1050 const struct bt_port_output_message_iterator *iterator)
8c6884d9
PP
1051{
1052 bt_object_put_ref(iterator);
1053}
1054
b09a5592
PP
1055void bt_self_component_port_input_message_iterator_get_ref(
1056 const struct bt_self_component_port_input_message_iterator *iterator)
8c6884d9
PP
1057{
1058 bt_object_get_ref(iterator);
1059}
1060
b09a5592
PP
1061void bt_self_component_port_input_message_iterator_put_ref(
1062 const struct bt_self_component_port_input_message_iterator *iterator)
8c6884d9
PP
1063{
1064 bt_object_put_ref(iterator);
1065}
This page took 0.231965 seconds and 4 git commands to generate.