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