Always evaluate BT_ASSERT(); add BT_ASSERT_DBG() for debug mode only
[babeltrace.git] / src / plugins / ctf / fs-sink / fs-sink.c
CommitLineData
15fe47e0
PP
1/*
2 * Copyright 2019 Philippe Proulx <pproulx@efficios.com>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
21 */
22
aa1a7452 23#define BT_COMP_LOG_SELF_COMP (fs_sink->self_comp)
ffa3b2b3 24#define BT_LOG_OUTPUT_LEVEL (fs_sink->log_level)
350ad6c1 25#define BT_LOG_TAG "PLUGIN/SINK.CTF.FS"
d9c39b0a 26#include "logging/comp-logging.h"
15fe47e0 27
3fadfbc0 28#include <babeltrace2/babeltrace.h>
15fe47e0
PP
29#include <stdio.h>
30#include <stdbool.h>
31#include <glib.h>
578e048b
MJ
32#include "common/assert.h"
33#include "ctfser/ctfser.h"
ce67f561 34#include "plugins/common/param-validation/param-validation.h"
15fe47e0
PP
35
36#include "fs-sink.h"
37#include "fs-sink-trace.h"
38#include "fs-sink-stream.h"
39#include "fs-sink-ctf-meta.h"
40#include "translate-trace-ir-to-ctf-ir.h"
41#include "translate-ctf-ir-to-tsdl.h"
42
43static
44const char * const in_port_name = "in";
45
46static
21a9f056 47bt_component_class_initialize_method_status ensure_output_dir_exists(
15fe47e0
PP
48 struct fs_sink_comp *fs_sink)
49{
21a9f056
FD
50 bt_component_class_initialize_method_status status =
51 BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK;
15fe47e0
PP
52 int ret;
53
54 ret = g_mkdir_with_parents(fs_sink->output_dir_path->str, 0755);
55 if (ret) {
aa1a7452
PP
56 BT_COMP_LOGE_ERRNO(
57 "Cannot create directories for output directory",
15fe47e0
PP
58 ": output-dir-path=\"%s\"",
59 fs_sink->output_dir_path->str);
21a9f056 60 status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR;
15fe47e0
PP
61 goto end;
62 }
63
64end:
65 return status;
66}
67
ce67f561
SM
68static struct bt_param_validation_map_value_entry_descr fs_sink_params_descr[] = {
69 { "path", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, { .type = BT_VALUE_TYPE_STRING } },
70 { "assume-single-trace", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_OPTIONAL, { .type = BT_VALUE_TYPE_BOOL } },
71 { "ignore-discarded-events", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_OPTIONAL, { .type = BT_VALUE_TYPE_BOOL } },
72 { "ignore-discarded-packets", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_OPTIONAL, { .type = BT_VALUE_TYPE_BOOL } },
73 { "quiet", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_OPTIONAL, { .type = BT_VALUE_TYPE_BOOL } },
74 BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END
75};
76
15fe47e0 77static
21a9f056 78bt_component_class_initialize_method_status
ce67f561 79configure_component(struct fs_sink_comp *fs_sink, const bt_value *params)
15fe47e0 80{
ce67f561 81 bt_component_class_initialize_method_status status;
15fe47e0 82 const bt_value *value;
ce67f561
SM
83 enum bt_param_validation_status validation_status;
84 gchar *validation_error;
15fe47e0 85
ce67f561
SM
86 validation_status = bt_param_validation_validate(params,
87 fs_sink_params_descr, &validation_error);
88 if (validation_status == BT_PARAM_VALIDATION_STATUS_VALIDATION_ERROR) {
21a9f056 89 status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR;
15fe47e0 90 goto end;
ce67f561
SM
91 } else if (validation_status == BT_PARAM_VALIDATION_STATUS_MEMORY_ERROR) {
92 status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR;
15fe47e0
PP
93 goto end;
94 }
95
ce67f561 96 value = bt_value_map_borrow_entry_value_const(params, "path");
15fe47e0
PP
97 g_string_assign(fs_sink->output_dir_path,
98 bt_value_string_get(value));
ce67f561 99
15fe47e0
PP
100 value = bt_value_map_borrow_entry_value_const(params,
101 "assume-single-trace");
102 if (value) {
15fe47e0
PP
103 fs_sink->assume_single_trace = (bool) bt_value_bool_get(value);
104 }
105
106 value = bt_value_map_borrow_entry_value_const(params,
107 "ignore-discarded-events");
108 if (value) {
15fe47e0
PP
109 fs_sink->ignore_discarded_events =
110 (bool) bt_value_bool_get(value);
111 }
112
113 value = bt_value_map_borrow_entry_value_const(params,
114 "ignore-discarded-packets");
115 if (value) {
15fe47e0
PP
116 fs_sink->ignore_discarded_packets =
117 (bool) bt_value_bool_get(value);
118 }
119
120 value = bt_value_map_borrow_entry_value_const(params,
121 "quiet");
122 if (value) {
15fe47e0
PP
123 fs_sink->quiet = (bool) bt_value_bool_get(value);
124 }
125
ce67f561
SM
126 status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK;
127
15fe47e0 128end:
ce67f561 129 g_free(validation_error);
15fe47e0
PP
130 return status;
131}
132
133static
134void destroy_fs_sink_comp(struct fs_sink_comp *fs_sink)
135{
136 if (!fs_sink) {
137 goto end;
138 }
139
140 if (fs_sink->output_dir_path) {
141 g_string_free(fs_sink->output_dir_path, TRUE);
142 fs_sink->output_dir_path = NULL;
143 }
144
145 if (fs_sink->traces) {
146 g_hash_table_destroy(fs_sink->traces);
147 fs_sink->traces = NULL;
148 }
149
150 BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_PUT_REF_AND_RESET(
151 fs_sink->upstream_iter);
152 g_free(fs_sink);
153
154end:
155 return;
156}
157
158BT_HIDDEN
21a9f056 159bt_component_class_initialize_method_status ctf_fs_sink_init(
59225a3e
SM
160 bt_self_component_sink *self_comp_sink,
161 bt_self_component_sink_configuration *config,
162 const bt_value *params,
15fe47e0
PP
163 void *init_method_data)
164{
21a9f056
FD
165 bt_component_class_initialize_method_status status =
166 BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK;
d24d5663 167 bt_self_component_add_port_status add_port_status;
15fe47e0 168 struct fs_sink_comp *fs_sink = NULL;
ffa3b2b3
PP
169 bt_self_component *self_comp =
170 bt_self_component_sink_as_self_component(self_comp_sink);
171 bt_logging_level log_level = bt_component_get_logging_level(
172 bt_self_component_as_component(self_comp));
15fe47e0
PP
173
174 fs_sink = g_new0(struct fs_sink_comp, 1);
175 if (!fs_sink) {
aa1a7452 176 BT_COMP_LOG_CUR_LVL(BT_LOG_ERROR, log_level, self_comp,
ffa3b2b3 177 "Failed to allocate one CTF FS sink structure.");
21a9f056 178 status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR;
15fe47e0
PP
179 goto end;
180 }
181
ffa3b2b3 182 fs_sink->log_level = log_level;
aa1a7452 183 fs_sink->self_comp = self_comp;
15fe47e0 184 fs_sink->output_dir_path = g_string_new(NULL);
15fe47e0 185 status = configure_component(fs_sink, params);
21a9f056 186 if (status != BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK) {
15fe47e0
PP
187 /* configure_component() logs errors */
188 goto end;
189 }
190
191 if (fs_sink->assume_single_trace &&
192 g_file_test(fs_sink->output_dir_path->str,
193 G_FILE_TEST_EXISTS)) {
aa1a7452 194 BT_COMP_LOGE("Single trace mode, but output path exists: "
15fe47e0 195 "output-path=\"%s\"", fs_sink->output_dir_path->str);
21a9f056 196 status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR;
15fe47e0
PP
197 goto end;
198 }
199
200 status = ensure_output_dir_exists(fs_sink);
21a9f056 201 if (status != BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK) {
15fe47e0
PP
202 /* ensure_output_dir_exists() logs errors */
203 goto end;
204 }
205
206 fs_sink->traces = g_hash_table_new_full(g_direct_hash, g_direct_equal,
207 NULL, (GDestroyNotify) fs_sink_trace_destroy);
208 if (!fs_sink->traces) {
aa1a7452 209 BT_COMP_LOGE_STR("Failed to allocate one GHashTable.");
21a9f056 210 status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR;
15fe47e0
PP
211 goto end;
212 }
213
d24d5663
PP
214 add_port_status = bt_self_component_sink_add_input_port(
215 self_comp_sink, in_port_name, NULL, NULL);
216 switch (add_port_status) {
217 case BT_SELF_COMPONENT_ADD_PORT_STATUS_ERROR:
21a9f056 218 status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR;
15fe47e0 219 goto end;
d24d5663 220 case BT_SELF_COMPONENT_ADD_PORT_STATUS_MEMORY_ERROR:
21a9f056 221 status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR;
d24d5663
PP
222 goto end;
223 default:
224 break;
15fe47e0
PP
225 }
226
ffa3b2b3 227 bt_self_component_set_data(self_comp, fs_sink);
15fe47e0
PP
228
229end:
21a9f056 230 if (status != BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK) {
15fe47e0
PP
231 destroy_fs_sink_comp(fs_sink);
232 }
233
234 return status;
235}
236
237static inline
238struct fs_sink_stream *borrow_stream(struct fs_sink_comp *fs_sink,
239 const bt_stream *ir_stream)
240{
241 const bt_trace *ir_trace = bt_stream_borrow_trace_const(ir_stream);
242 struct fs_sink_trace *trace;
243 struct fs_sink_stream *stream = NULL;
244
245 trace = g_hash_table_lookup(fs_sink->traces, ir_trace);
91d81473 246 if (G_UNLIKELY(!trace)) {
15fe47e0
PP
247 if (fs_sink->assume_single_trace &&
248 g_hash_table_size(fs_sink->traces) > 0) {
aa1a7452 249 BT_COMP_LOGE("Single trace mode, but getting more than one trace: "
15fe47e0
PP
250 "stream-name=\"%s\"",
251 bt_stream_get_name(ir_stream));
252 goto end;
253 }
254
255 trace = fs_sink_trace_create(fs_sink, ir_trace);
256 if (!trace) {
257 goto end;
258 }
259 }
260
261 stream = g_hash_table_lookup(trace->streams, ir_stream);
91d81473 262 if (G_UNLIKELY(!stream)) {
15fe47e0
PP
263 stream = fs_sink_stream_create(trace, ir_stream);
264 if (!stream) {
265 goto end;
266 }
267 }
268
269end:
270 return stream;
271}
272
273static inline
d24d5663
PP
274bt_component_class_sink_consume_method_status handle_event_msg(
275 struct fs_sink_comp *fs_sink, const bt_message *msg)
15fe47e0
PP
276{
277 int ret;
d24d5663
PP
278 bt_component_class_sink_consume_method_status status =
279 BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK;
15fe47e0
PP
280 const bt_event *ir_event = bt_message_event_borrow_event_const(msg);
281 const bt_stream *ir_stream = bt_event_borrow_stream_const(ir_event);
282 struct fs_sink_stream *stream;
283 struct fs_sink_ctf_event_class *ec = NULL;
284 const bt_clock_snapshot *cs = NULL;
285
286 stream = borrow_stream(fs_sink, ir_stream);
91d81473 287 if (G_UNLIKELY(!stream)) {
d24d5663 288 status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR;
15fe47e0
PP
289 goto end;
290 }
291
aa1a7452
PP
292 ret = try_translate_event_class_trace_ir_to_ctf_ir(fs_sink,
293 stream->sc, bt_event_borrow_class_const(ir_event), &ec);
15fe47e0 294 if (ret) {
d24d5663 295 status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR;
15fe47e0
PP
296 goto end;
297 }
298
98b15851 299 BT_ASSERT_DBG(ec);
15fe47e0
PP
300
301 if (stream->sc->default_clock_class) {
0cbc2c33
PP
302 cs = bt_message_event_borrow_default_clock_snapshot_const(
303 msg);
15fe47e0
PP
304 }
305
26fc5aed
PP
306 /*
307 * If this event's stream does not support packets, then we
308 * lazily create artificial packets.
309 *
310 * The size of an artificial packet is arbitrarily at least
311 * 4 MiB (it usually is greater because we close it when
312 * comes the time to write a new event and the packet's content
313 * size is >= 4 MiB), except the last one which can be smaller.
314 */
315 if (G_UNLIKELY(!stream->sc->has_packets)) {
316 if (stream->packet_state.is_open &&
317 bt_ctfser_get_offset_in_current_packet_bits(&stream->ctfser) / 8 >=
318 4 * 1024 * 1024) {
319 /*
320 * Stream's current packet is larger than 4 MiB:
321 * close it. A new packet will be opened just
322 * below.
323 */
324 ret = fs_sink_stream_close_packet(stream, NULL);
325 if (ret) {
326 status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR;
327 goto end;
328 }
329 }
330
331 if (!stream->packet_state.is_open) {
332 /* Stream's packet is not currently opened: open it */
333 ret = fs_sink_stream_open_packet(stream, NULL, NULL);
334 if (ret) {
335 status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR;
336 goto end;
337 }
338 }
339 }
340
98b15851 341 BT_ASSERT_DBG(stream->packet_state.is_open);
15fe47e0 342 ret = fs_sink_stream_write_event(stream, cs, ir_event, ec);
91d81473 343 if (G_UNLIKELY(ret)) {
d24d5663 344 status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR;
15fe47e0
PP
345 goto end;
346 }
347
348end:
349 return status;
350}
351
352static inline
d24d5663 353bt_component_class_sink_consume_method_status handle_packet_beginning_msg(
15fe47e0
PP
354 struct fs_sink_comp *fs_sink, const bt_message *msg)
355{
356 int ret;
d24d5663
PP
357 bt_component_class_sink_consume_method_status status =
358 BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK;
15fe47e0
PP
359 const bt_packet *ir_packet =
360 bt_message_packet_beginning_borrow_packet_const(msg);
361 const bt_stream *ir_stream = bt_packet_borrow_stream_const(ir_packet);
362 struct fs_sink_stream *stream;
363 const bt_clock_snapshot *cs = NULL;
364
365 stream = borrow_stream(fs_sink, ir_stream);
91d81473 366 if (G_UNLIKELY(!stream)) {
d24d5663 367 status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR;
15fe47e0
PP
368 goto end;
369 }
370
ffb5c13c 371 if (stream->sc->packets_have_ts_begin) {
0cbc2c33
PP
372 cs = bt_message_packet_beginning_borrow_default_clock_snapshot_const(
373 msg);
15fe47e0
PP
374 BT_ASSERT(cs);
375 }
376
491c35cc
PP
377 /*
378 * If we previously received a discarded events message with
379 * a time range, make sure that its beginning time matches what's
380 * expected for CTF 1.8, that is:
381 *
382 * * Its beginning time is the previous packet's end
383 * time (or the current packet's beginning time if
384 * this is the first packet).
385 *
386 * We check this here instead of in handle_packet_end_msg()
387 * because we want to catch any incompatible message as early as
388 * possible to report the error.
389 *
390 * Validation of the discarded events message's end time is
391 * performed in handle_packet_end_msg().
392 */
15fe47e0 393 if (stream->discarded_events_state.in_range) {
ffb5c13c
PP
394 uint64_t expected_cs;
395
491c35cc
PP
396 /*
397 * `stream->discarded_events_state.in_range` is only set
398 * when the stream class's discarded events have a time
399 * range.
400 *
401 * It is required that the packet beginning and end
402 * messages for this stream class have times when
403 * discarded events have a time range.
404 */
ffb5c13c
PP
405 BT_ASSERT(stream->sc->discarded_events_has_ts);
406 BT_ASSERT(stream->sc->packets_have_ts_begin);
407 BT_ASSERT(stream->sc->packets_have_ts_end);
408
ffb5c13c
PP
409 if (stream->prev_packet_state.end_cs == UINT64_C(-1)) {
410 /* We're opening the first packet */
411 expected_cs = bt_clock_snapshot_get_value(cs);
412 } else {
413 expected_cs = stream->prev_packet_state.end_cs;
15fe47e0 414 }
15fe47e0 415
ffb5c13c
PP
416 if (stream->discarded_events_state.beginning_cs !=
417 expected_cs) {
aa1a7452 418 BT_COMP_LOGE("Incompatible discarded events message: "
ffb5c13c
PP
419 "unexpected beginning time: "
420 "beginning-cs-val=%" PRIu64 ", "
421 "expected-beginning-cs-val=%" PRIu64 ", "
15fe47e0
PP
422 "stream-id=%" PRIu64 ", stream-name=\"%s\", "
423 "trace-name=\"%s\", path=\"%s/%s\"",
ffb5c13c
PP
424 stream->discarded_events_state.beginning_cs,
425 expected_cs,
15fe47e0
PP
426 bt_stream_get_id(ir_stream),
427 bt_stream_get_name(ir_stream),
428 bt_trace_get_name(
429 bt_stream_borrow_trace_const(ir_stream)),
430 stream->trace->path->str, stream->file_name->str);
d24d5663 431 status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR;
15fe47e0
PP
432 goto end;
433 }
ffb5c13c
PP
434 }
435
491c35cc
PP
436 /*
437 * If we previously received a discarded packets message with a
438 * time range, make sure that its beginning and end times match
439 * what's expected for CTF 1.8, that is:
440 *
441 * * Its beginning time is the previous packet's end time.
442 *
443 * * Its end time is the current packet's beginning time.
444 */
ffb5c13c
PP
445 if (stream->discarded_packets_state.in_range) {
446 uint64_t expected_end_cs;
447
491c35cc
PP
448 /*
449 * `stream->discarded_packets_state.in_range` is only
450 * set when the stream class's discarded packets have a
451 * time range.
452 *
453 * It is required that the packet beginning and end
454 * messages for this stream class have times when
455 * discarded packets have a time range.
456 */
ffb5c13c
PP
457 BT_ASSERT(stream->sc->discarded_packets_has_ts);
458 BT_ASSERT(stream->sc->packets_have_ts_begin);
459 BT_ASSERT(stream->sc->packets_have_ts_end);
15fe47e0
PP
460
461 /*
491c35cc
PP
462 * It is not supported to have a discarded packets
463 * message _before_ the first packet: we cannot validate
464 * that its beginning time is compatible with CTF 1.8 in
465 * this case.
15fe47e0 466 */
ffb5c13c 467 if (stream->prev_packet_state.end_cs == UINT64_C(-1)) {
aa1a7452 468 BT_COMP_LOGE("Incompatible discarded packets message "
ffb5c13c
PP
469 "occuring before the stream's first packet: "
470 "stream-id=%" PRIu64 ", stream-name=\"%s\", "
471 "trace-name=\"%s\", path=\"%s/%s\"",
472 bt_stream_get_id(ir_stream),
473 bt_stream_get_name(ir_stream),
474 bt_trace_get_name(
475 bt_stream_borrow_trace_const(ir_stream)),
476 stream->trace->path->str, stream->file_name->str);
d24d5663 477 status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR;
ffb5c13c
PP
478 goto end;
479 }
480
481 if (stream->discarded_packets_state.beginning_cs !=
482 stream->prev_packet_state.end_cs) {
aa1a7452 483 BT_COMP_LOGE("Incompatible discarded packets message: "
ffb5c13c
PP
484 "unexpected beginning time: "
485 "beginning-cs-val=%" PRIu64 ", "
486 "expected-beginning-cs-val=%" PRIu64 ", "
487 "stream-id=%" PRIu64 ", stream-name=\"%s\", "
488 "trace-name=\"%s\", path=\"%s/%s\"",
489 stream->discarded_packets_state.beginning_cs,
490 stream->prev_packet_state.end_cs,
491 bt_stream_get_id(ir_stream),
492 bt_stream_get_name(ir_stream),
493 bt_trace_get_name(
494 bt_stream_borrow_trace_const(ir_stream)),
495 stream->trace->path->str, stream->file_name->str);
d24d5663 496 status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR;
ffb5c13c 497 goto end;
15fe47e0 498 }
ffb5c13c
PP
499
500 expected_end_cs = bt_clock_snapshot_get_value(cs);
501
502 if (stream->discarded_packets_state.end_cs !=
503 expected_end_cs) {
aa1a7452 504 BT_COMP_LOGE("Incompatible discarded packets message: "
ffb5c13c
PP
505 "unexpected end time: "
506 "end-cs-val=%" PRIu64 ", "
507 "expected-end-cs-val=%" PRIu64 ", "
508 "stream-id=%" PRIu64 ", stream-name=\"%s\", "
509 "trace-name=\"%s\", path=\"%s/%s\"",
510 stream->discarded_packets_state.end_cs,
511 expected_end_cs,
512 bt_stream_get_id(ir_stream),
513 bt_stream_get_name(ir_stream),
514 bt_trace_get_name(
515 bt_stream_borrow_trace_const(ir_stream)),
516 stream->trace->path->str, stream->file_name->str);
d24d5663 517 status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR;
ffb5c13c
PP
518 goto end;
519 }
520 }
521
491c35cc
PP
522 /*
523 * We're not in a discarded packets time range anymore since we
524 * require that the discarded packets time ranges go from one
525 * packet's end time to the next packet's beginning time, and
526 * we're handling a packet beginning message here.
527 */
528 stream->discarded_packets_state.in_range = false;
15fe47e0 529
15fe47e0
PP
530 ret = fs_sink_stream_open_packet(stream, cs, ir_packet);
531 if (ret) {
d24d5663 532 status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR;
15fe47e0
PP
533 goto end;
534 }
535
536end:
537 return status;
538}
539
540static inline
d24d5663 541bt_component_class_sink_consume_method_status handle_packet_end_msg(
15fe47e0
PP
542 struct fs_sink_comp *fs_sink, const bt_message *msg)
543{
544 int ret;
d24d5663
PP
545 bt_component_class_sink_consume_method_status status =
546 BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK;
15fe47e0
PP
547 const bt_packet *ir_packet =
548 bt_message_packet_end_borrow_packet_const(msg);
549 const bt_stream *ir_stream = bt_packet_borrow_stream_const(ir_packet);
550 struct fs_sink_stream *stream;
551 const bt_clock_snapshot *cs = NULL;
552
553 stream = borrow_stream(fs_sink, ir_stream);
91d81473 554 if (G_UNLIKELY(!stream)) {
d24d5663 555 status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR;
15fe47e0
PP
556 goto end;
557 }
558
ffb5c13c 559 if (stream->sc->packets_have_ts_end) {
0cbc2c33
PP
560 cs = bt_message_packet_end_borrow_default_clock_snapshot_const(
561 msg);
15fe47e0
PP
562 BT_ASSERT(cs);
563 }
564
491c35cc
PP
565 /*
566 * If we previously received a discarded events message with
567 * a time range, make sure that its end time matches what's
568 * expected for CTF 1.8, that is:
569 *
570 * * Its end time is the current packet's end time.
571 *
572 * Validation of the discarded events message's beginning time
573 * is performed in handle_packet_beginning_msg().
574 */
15fe47e0 575 if (stream->discarded_events_state.in_range) {
ffb5c13c
PP
576 uint64_t expected_cs;
577
491c35cc
PP
578 /*
579 * `stream->discarded_events_state.in_range` is only set
580 * when the stream class's discarded events have a time
581 * range.
582 *
583 * It is required that the packet beginning and end
584 * messages for this stream class have times when
585 * discarded events have a time range.
586 */
ffb5c13c
PP
587 BT_ASSERT(stream->sc->discarded_events_has_ts);
588 BT_ASSERT(stream->sc->packets_have_ts_begin);
589 BT_ASSERT(stream->sc->packets_have_ts_end);
590
ffb5c13c
PP
591 expected_cs = bt_clock_snapshot_get_value(cs);
592
593 if (stream->discarded_events_state.end_cs != expected_cs) {
aa1a7452 594 BT_COMP_LOGE("Incompatible discarded events message: "
ffb5c13c
PP
595 "unexpected end time: "
596 "end-cs-val=%" PRIu64 ", "
597 "expected-end-cs-val=%" PRIu64 ", "
598 "stream-id=%" PRIu64 ", stream-name=\"%s\", "
599 "trace-name=\"%s\", path=\"%s/%s\"",
600 stream->discarded_events_state.end_cs,
601 expected_cs,
602 bt_stream_get_id(ir_stream),
603 bt_stream_get_name(ir_stream),
604 bt_trace_get_name(
605 bt_stream_borrow_trace_const(ir_stream)),
606 stream->trace->path->str, stream->file_name->str);
d24d5663 607 status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR;
ffb5c13c 608 goto end;
15fe47e0
PP
609 }
610 }
611
612 ret = fs_sink_stream_close_packet(stream, cs);
613 if (ret) {
d24d5663 614 status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR;
15fe47e0
PP
615 goto end;
616 }
617
491c35cc
PP
618 /*
619 * We're not in a discarded events time range anymore since we
620 * require that the discarded events time ranges go from one
621 * packet's end time to the next packet's end time, and we're
622 * handling a packet end message here.
623 */
624 stream->discarded_events_state.in_range = false;
15fe47e0
PP
625
626end:
627 return status;
628}
629
630static inline
d24d5663 631bt_component_class_sink_consume_method_status handle_stream_beginning_msg(
15fe47e0
PP
632 struct fs_sink_comp *fs_sink, const bt_message *msg)
633{
d24d5663
PP
634 bt_component_class_sink_consume_method_status status =
635 BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK;
15fe47e0
PP
636 const bt_stream *ir_stream =
637 bt_message_stream_beginning_borrow_stream_const(msg);
649934d2
PP
638 const bt_stream_class *ir_sc =
639 bt_stream_borrow_class_const(ir_stream);
15fe47e0 640 struct fs_sink_stream *stream;
ffb5c13c 641 bool packets_have_beginning_end_cs =
9b24b6aa
PP
642 bt_stream_class_packets_have_beginning_default_clock_snapshot(ir_sc) &&
643 bt_stream_class_packets_have_end_default_clock_snapshot(ir_sc);
15fe47e0 644
26fc5aed
PP
645 /*
646 * Not supported: discarded events or discarded packets support
647 * without packets support. Packets are the way to know where
648 * discarded events/packets occured in CTF 1.8.
649 */
650 if (!bt_stream_class_supports_packets(ir_sc)) {
651 BT_ASSERT(!bt_stream_class_supports_discarded_packets(ir_sc));
652
653 if (!fs_sink->ignore_discarded_events &&
654 bt_stream_class_supports_discarded_events(ir_sc)) {
655 BT_COMP_LOGE("Unsupported stream: "
656 "stream does not support packets, "
657 "but supports discarded events: "
658 "stream-addr=%p, "
659 "stream-id=%" PRIu64 ", "
660 "stream-name=\"%s\"",
661 ir_stream, bt_stream_get_id(ir_stream),
662 bt_stream_get_name(ir_stream));
663 status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR;
664 goto end;
665 }
666 }
667
649934d2 668 /*
ffb5c13c
PP
669 * Not supported: discarded events with default clock snapshots,
670 * but packet beginning/end without default clock snapshot.
649934d2 671 */
ffb5c13c
PP
672 if (!fs_sink->ignore_discarded_events &&
673 bt_stream_class_discarded_events_have_default_clock_snapshots(ir_sc) &&
674 !packets_have_beginning_end_cs) {
aa1a7452 675 BT_COMP_LOGE("Unsupported stream: discarded events have "
ffb5c13c
PP
676 "default clock snapshots, but packets have no "
677 "beginning and/or end default clock snapshots: "
678 "stream-addr=%p, "
679 "stream-id=%" PRIu64 ", "
680 "stream-name=\"%s\"",
681 ir_stream, bt_stream_get_id(ir_stream),
682 bt_stream_get_name(ir_stream));
d24d5663 683 status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR;
ffb5c13c
PP
684 goto end;
685 }
2e90378a 686
ffb5c13c
PP
687 /*
688 * Not supported: discarded packets with default clock
689 * snapshots, but packet beginning/end without default clock
690 * snapshot.
691 */
692 if (!fs_sink->ignore_discarded_packets &&
693 bt_stream_class_discarded_packets_have_default_clock_snapshots(ir_sc) &&
694 !packets_have_beginning_end_cs) {
aa1a7452 695 BT_COMP_LOGE("Unsupported stream: discarded packets have "
ffb5c13c
PP
696 "default clock snapshots, but packets have no "
697 "beginning and/or end default clock snapshots: "
698 "stream-addr=%p, "
699 "stream-id=%" PRIu64 ", "
700 "stream-name=\"%s\"",
701 ir_stream, bt_stream_get_id(ir_stream),
702 bt_stream_get_name(ir_stream));
d24d5663 703 status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR;
ffb5c13c 704 goto end;
649934d2
PP
705 }
706
15fe47e0
PP
707 stream = borrow_stream(fs_sink, ir_stream);
708 if (!stream) {
d24d5663 709 status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR;
15fe47e0
PP
710 goto end;
711 }
712
aa1a7452 713 BT_COMP_LOGI("Created new, empty stream file: "
15fe47e0
PP
714 "stream-id=%" PRIu64 ", stream-name=\"%s\", "
715 "trace-name=\"%s\", path=\"%s/%s\"",
716 bt_stream_get_id(ir_stream), bt_stream_get_name(ir_stream),
717 bt_trace_get_name(bt_stream_borrow_trace_const(ir_stream)),
718 stream->trace->path->str, stream->file_name->str);
719
720end:
721 return status;
722}
723
724static inline
d24d5663
PP
725bt_component_class_sink_consume_method_status handle_stream_end_msg(
726 struct fs_sink_comp *fs_sink, const bt_message *msg)
15fe47e0 727{
d24d5663
PP
728 bt_component_class_sink_consume_method_status status =
729 BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK;
15fe47e0
PP
730 const bt_stream *ir_stream =
731 bt_message_stream_end_borrow_stream_const(msg);
732 struct fs_sink_stream *stream;
733
734 stream = borrow_stream(fs_sink, ir_stream);
735 if (!stream) {
d24d5663 736 status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR;
15fe47e0
PP
737 goto end;
738 }
739
26fc5aed
PP
740 if (G_UNLIKELY(!stream->sc->has_packets &&
741 stream->packet_state.is_open)) {
742 /* Close stream's current artificial packet */
743 int ret = fs_sink_stream_close_packet(stream, NULL);
744
745 if (ret) {
746 status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR;
747 goto end;
748 }
749 }
750
aa1a7452 751 BT_COMP_LOGI("Closing stream file: "
15fe47e0
PP
752 "stream-id=%" PRIu64 ", stream-name=\"%s\", "
753 "trace-name=\"%s\", path=\"%s/%s\"",
754 bt_stream_get_id(ir_stream), bt_stream_get_name(ir_stream),
755 bt_trace_get_name(bt_stream_borrow_trace_const(ir_stream)),
756 stream->trace->path->str, stream->file_name->str);
757
758 /*
759 * This destroys the stream object and frees all its resources,
760 * closing the stream file.
761 */
762 g_hash_table_remove(stream->trace->streams, ir_stream);
763
764end:
765 return status;
766}
767
768static inline
d24d5663 769bt_component_class_sink_consume_method_status handle_discarded_events_msg(
15fe47e0
PP
770 struct fs_sink_comp *fs_sink, const bt_message *msg)
771{
d24d5663
PP
772 bt_component_class_sink_consume_method_status status =
773 BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK;
15fe47e0
PP
774 const bt_stream *ir_stream =
775 bt_message_discarded_events_borrow_stream_const(msg);
776 struct fs_sink_stream *stream;
777 const bt_clock_snapshot *cs = NULL;
778 bt_property_availability avail;
779 uint64_t count;
780
781 stream = borrow_stream(fs_sink, ir_stream);
782 if (!stream) {
d24d5663 783 status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR;
15fe47e0
PP
784 goto end;
785 }
786
787 if (fs_sink->ignore_discarded_events) {
aa1a7452 788 BT_COMP_LOGI("Ignoring discarded events message: "
15fe47e0
PP
789 "stream-id=%" PRIu64 ", stream-name=\"%s\", "
790 "trace-name=\"%s\", path=\"%s/%s\"",
791 bt_stream_get_id(ir_stream),
792 bt_stream_get_name(ir_stream),
793 bt_trace_get_name(
794 bt_stream_borrow_trace_const(ir_stream)),
795 stream->trace->path->str, stream->file_name->str);
796 goto end;
797 }
798
799 if (stream->discarded_events_state.in_range) {
aa1a7452 800 BT_COMP_LOGE("Unsupported contiguous discarded events message: "
15fe47e0
PP
801 "stream-id=%" PRIu64 ", stream-name=\"%s\", "
802 "trace-name=\"%s\", path=\"%s/%s\"",
803 bt_stream_get_id(ir_stream),
804 bt_stream_get_name(ir_stream),
805 bt_trace_get_name(
806 bt_stream_borrow_trace_const(ir_stream)),
807 stream->trace->path->str, stream->file_name->str);
d24d5663 808 status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR;
15fe47e0
PP
809 goto end;
810 }
811
491c35cc
PP
812 /*
813 * If we're currently in an opened packet (got a packet
814 * beginning message, but no packet end message yet), we do not
815 * support having a discarded events message with a time range
816 * because we require that the discarded events message's time
817 * range go from a packet's end time to the next packet's end
818 * time.
819 */
ffb5c13c
PP
820 if (stream->packet_state.is_open &&
821 stream->sc->discarded_events_has_ts) {
aa1a7452 822 BT_COMP_LOGE("Unsupported discarded events message with "
ffb5c13c 823 "default clock snapshots occuring within a packet: "
15fe47e0
PP
824 "stream-id=%" PRIu64 ", stream-name=\"%s\", "
825 "trace-name=\"%s\", path=\"%s/%s\"",
826 bt_stream_get_id(ir_stream),
827 bt_stream_get_name(ir_stream),
828 bt_trace_get_name(
829 bt_stream_borrow_trace_const(ir_stream)),
830 stream->trace->path->str, stream->file_name->str);
d24d5663 831 status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR;
15fe47e0
PP
832 goto end;
833 }
834
ffb5c13c 835 if (stream->sc->discarded_events_has_ts) {
491c35cc
PP
836 /*
837 * Make the stream's state be in the time range of a
838 * discarded events message since we have the message's
839 * time range (`stream->sc->discarded_events_has_ts`).
840 */
ffb5c13c 841 stream->discarded_events_state.in_range = true;
15fe47e0 842
15fe47e0
PP
843 /*
844 * The clock snapshot values will be validated when
491c35cc
PP
845 * handling the next packet beginning and end messages
846 * (next calls to handle_packet_beginning_msg() and
847 * handle_packet_end_msg()).
15fe47e0 848 */
9b24b6aa 849 cs = bt_message_discarded_events_borrow_beginning_default_clock_snapshot_const(
0cbc2c33 850 msg);
15fe47e0
PP
851 BT_ASSERT(cs);
852 stream->discarded_events_state.beginning_cs =
853 bt_clock_snapshot_get_value(cs);
9b24b6aa 854 cs = bt_message_discarded_events_borrow_end_default_clock_snapshot_const(
0cbc2c33 855 msg);
15fe47e0 856 BT_ASSERT(cs);
ffb5c13c 857 stream->discarded_events_state.end_cs = bt_clock_snapshot_get_value(cs);
15fe47e0
PP
858 }
859
860 avail = bt_message_discarded_events_get_count(msg, &count);
861 if (avail != BT_PROPERTY_AVAILABILITY_AVAILABLE) {
491c35cc
PP
862 /*
863 * There's no specific count of discarded events: set it
864 * to 1 so that we know that we at least discarded
865 * something.
866 */
15fe47e0
PP
867 count = 1;
868 }
869
870 stream->packet_state.discarded_events_counter += count;
871
872end:
873 return status;
874}
875
876static inline
d24d5663 877bt_component_class_sink_consume_method_status handle_discarded_packets_msg(
15fe47e0
PP
878 struct fs_sink_comp *fs_sink, const bt_message *msg)
879{
d24d5663
PP
880 bt_component_class_sink_consume_method_status status =
881 BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK;
15fe47e0
PP
882 const bt_stream *ir_stream =
883 bt_message_discarded_packets_borrow_stream_const(msg);
884 struct fs_sink_stream *stream;
885 const bt_clock_snapshot *cs = NULL;
886 bt_property_availability avail;
887 uint64_t count;
888
889 stream = borrow_stream(fs_sink, ir_stream);
890 if (!stream) {
d24d5663 891 status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR;
15fe47e0
PP
892 goto end;
893 }
894
895 if (fs_sink->ignore_discarded_packets) {
aa1a7452 896 BT_COMP_LOGI("Ignoring discarded packets message: "
15fe47e0
PP
897 "stream-id=%" PRIu64 ", stream-name=\"%s\", "
898 "trace-name=\"%s\", path=\"%s/%s\"",
899 bt_stream_get_id(ir_stream),
900 bt_stream_get_name(ir_stream),
901 bt_trace_get_name(
902 bt_stream_borrow_trace_const(ir_stream)),
903 stream->trace->path->str, stream->file_name->str);
904 goto end;
905 }
906
907 if (stream->discarded_packets_state.in_range) {
aa1a7452 908 BT_COMP_LOGE("Unsupported contiguous discarded packets message: "
15fe47e0
PP
909 "stream-id=%" PRIu64 ", stream-name=\"%s\", "
910 "trace-name=\"%s\", path=\"%s/%s\"",
911 bt_stream_get_id(ir_stream),
912 bt_stream_get_name(ir_stream),
913 bt_trace_get_name(
914 bt_stream_borrow_trace_const(ir_stream)),
915 stream->trace->path->str, stream->file_name->str);
d24d5663 916 status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR;
15fe47e0
PP
917 goto end;
918 }
919
491c35cc
PP
920 /*
921 * Discarded packets messages are guaranteed to occur between
922 * packets.
923 */
ffb5c13c 924 BT_ASSERT(!stream->packet_state.is_open);
15fe47e0 925
ffb5c13c 926 if (stream->sc->discarded_packets_has_ts) {
491c35cc
PP
927 /*
928 * Make the stream's state be in the time range of a
929 * discarded packets message since we have the message's
930 * time range (`stream->sc->discarded_packets_has_ts`).
931 */
ffb5c13c 932 stream->discarded_packets_state.in_range = true;
15fe47e0 933
15fe47e0
PP
934 /*
935 * The clock snapshot values will be validated when
491c35cc
PP
936 * handling the next packet beginning message (next call
937 * to handle_packet_beginning_msg()).
15fe47e0 938 */
9b24b6aa 939 cs = bt_message_discarded_packets_borrow_beginning_default_clock_snapshot_const(
0cbc2c33 940 msg);
15fe47e0
PP
941 BT_ASSERT(cs);
942 stream->discarded_packets_state.beginning_cs =
943 bt_clock_snapshot_get_value(cs);
9b24b6aa 944 cs = bt_message_discarded_packets_borrow_end_default_clock_snapshot_const(
0cbc2c33 945 msg);
15fe47e0
PP
946 BT_ASSERT(cs);
947 stream->discarded_packets_state.end_cs =
948 bt_clock_snapshot_get_value(cs);
15fe47e0
PP
949 }
950
951 avail = bt_message_discarded_packets_get_count(msg, &count);
952 if (avail != BT_PROPERTY_AVAILABILITY_AVAILABLE) {
491c35cc
PP
953 /*
954 * There's no specific count of discarded packets: set
955 * it to 1 so that we know that we at least discarded
956 * something.
957 */
15fe47e0
PP
958 count = 1;
959 }
960
961 stream->packet_state.seq_num += count;
962
963end:
964 return status;
965}
966
967static inline
968void put_messages(bt_message_array_const msgs, uint64_t count)
969{
970 uint64_t i;
971
972 for (i = 0; i < count; i++) {
973 BT_MESSAGE_PUT_REF_AND_RESET(msgs[i]);
974 }
975}
976
977BT_HIDDEN
d24d5663
PP
978bt_component_class_sink_consume_method_status ctf_fs_sink_consume(
979 bt_self_component_sink *self_comp)
15fe47e0 980{
d24d5663
PP
981 bt_component_class_sink_consume_method_status status =
982 BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK;
15fe47e0 983 struct fs_sink_comp *fs_sink;
d24d5663 984 bt_message_iterator_next_status next_status;
15fe47e0
PP
985 uint64_t msg_count = 0;
986 bt_message_array_const msgs;
987
988 fs_sink = bt_self_component_get_data(
989 bt_self_component_sink_as_self_component(self_comp));
98b15851
PP
990 BT_ASSERT_DBG(fs_sink);
991 BT_ASSERT_DBG(fs_sink->upstream_iter);
15fe47e0
PP
992
993 /* Consume messages */
d24d5663 994 next_status = bt_self_component_port_input_message_iterator_next(
15fe47e0 995 fs_sink->upstream_iter, &msgs, &msg_count);
d24d5663
PP
996 if (next_status < 0) {
997 status = (int) next_status;
15fe47e0
PP
998 goto end;
999 }
1000
d24d5663
PP
1001 switch (next_status) {
1002 case BT_MESSAGE_ITERATOR_NEXT_STATUS_OK:
15fe47e0
PP
1003 {
1004 uint64_t i;
1005
1006 for (i = 0; i < msg_count; i++) {
1007 const bt_message *msg = msgs[i];
1008
98b15851 1009 BT_ASSERT_DBG(msg);
15fe47e0
PP
1010
1011 switch (bt_message_get_type(msg)) {
1012 case BT_MESSAGE_TYPE_EVENT:
1013 status = handle_event_msg(fs_sink, msg);
1014 break;
1015 case BT_MESSAGE_TYPE_PACKET_BEGINNING:
1016 status = handle_packet_beginning_msg(
1017 fs_sink, msg);
1018 break;
1019 case BT_MESSAGE_TYPE_PACKET_END:
1020 status = handle_packet_end_msg(
1021 fs_sink, msg);
1022 break;
1023 case BT_MESSAGE_TYPE_MESSAGE_ITERATOR_INACTIVITY:
1024 /* Ignore */
aa1a7452 1025 BT_COMP_LOGD_STR("Ignoring message iterator inactivity message.");
15fe47e0
PP
1026 break;
1027 case BT_MESSAGE_TYPE_STREAM_BEGINNING:
1028 status = handle_stream_beginning_msg(
1029 fs_sink, msg);
1030 break;
1031 case BT_MESSAGE_TYPE_STREAM_END:
1032 status = handle_stream_end_msg(
1033 fs_sink, msg);
1034 break;
15fe47e0
PP
1035 case BT_MESSAGE_TYPE_DISCARDED_EVENTS:
1036 status = handle_discarded_events_msg(
1037 fs_sink, msg);
1038 break;
1039 case BT_MESSAGE_TYPE_DISCARDED_PACKETS:
1040 status = handle_discarded_packets_msg(
1041 fs_sink, msg);
1042 break;
1043 default:
1044 abort();
1045 }
1046
1047 BT_MESSAGE_PUT_REF_AND_RESET(msgs[i]);
1048
d24d5663 1049 if (status != BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK) {
aa1a7452 1050 BT_COMP_LOGE("Failed to handle message: "
15fe47e0
PP
1051 "generated CTF traces could be incomplete: "
1052 "output-dir-path=\"%s\"",
1053 fs_sink->output_dir_path->str);
1054 goto error;
1055 }
1056 }
1057
1058 break;
1059 }
d24d5663
PP
1060 case BT_MESSAGE_ITERATOR_NEXT_STATUS_AGAIN:
1061 status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_AGAIN;
15fe47e0 1062 break;
d24d5663 1063 case BT_MESSAGE_ITERATOR_NEXT_STATUS_END:
15fe47e0 1064 /* TODO: Finalize all traces (should already be done?) */
d24d5663 1065 status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_END;
15fe47e0 1066 break;
d24d5663
PP
1067 case BT_MESSAGE_ITERATOR_NEXT_STATUS_MEMORY_ERROR:
1068 status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_MEMORY_ERROR;
15fe47e0 1069 break;
d24d5663
PP
1070 case BT_MESSAGE_ITERATOR_NEXT_STATUS_ERROR:
1071 status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_MEMORY_ERROR;
15fe47e0
PP
1072 break;
1073 default:
1074 break;
1075 }
1076
1077 goto end;
1078
1079error:
d24d5663 1080 BT_ASSERT(status != BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK);
15fe47e0
PP
1081 put_messages(msgs, msg_count);
1082
1083end:
1084 return status;
1085}
1086
1087BT_HIDDEN
e803df70
SM
1088bt_component_class_sink_graph_is_configured_method_status
1089ctf_fs_sink_graph_is_configured(
15fe47e0
PP
1090 bt_self_component_sink *self_comp)
1091{
e803df70
SM
1092 bt_component_class_sink_graph_is_configured_method_status status;
1093 bt_self_component_port_input_message_iterator_create_from_sink_component_status
1094 msg_iter_status;
15fe47e0
PP
1095 struct fs_sink_comp *fs_sink = bt_self_component_get_data(
1096 bt_self_component_sink_as_self_component(self_comp));
1097
e803df70 1098 msg_iter_status =
ca02df0a
PP
1099 bt_self_component_port_input_message_iterator_create_from_sink_component(
1100 self_comp,
15fe47e0 1101 bt_self_component_sink_borrow_input_port_by_name(
e803df70
SM
1102 self_comp, in_port_name), &fs_sink->upstream_iter);
1103 if (msg_iter_status != BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_CREATE_FROM_SINK_COMPONENT_STATUS_OK) {
1104 status = (int) msg_iter_status;
15fe47e0
PP
1105 goto end;
1106 }
1107
e803df70 1108 status = BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_OK;
15fe47e0
PP
1109end:
1110 return status;
1111}
1112
1113BT_HIDDEN
1114void ctf_fs_sink_finalize(bt_self_component_sink *self_comp)
1115{
1116 struct fs_sink_comp *fs_sink = bt_self_component_get_data(
1117 bt_self_component_sink_as_self_component(self_comp));
1118
1119 destroy_fs_sink_comp(fs_sink);
1120}
This page took 0.089426 seconds and 4 git commands to generate.