support adding streams on non-static traces
[babeltrace.git] / plugins / ctf / fs-sink / write.c
CommitLineData
bc506aa5
JD
1/*
2 * writer.c
3 *
4 * Babeltrace CTF Writer Output Plugin Event Handling
5 *
6 * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
7 *
8 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 * of this software and associated documentation files (the "Software"), to deal
12 * in the Software without restriction, including without limitation the rights
13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the Software is
15 * furnished to do so, subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 * SOFTWARE.
27 */
28
29#include <babeltrace/ctf-ir/event.h>
30#include <babeltrace/ctf-ir/packet.h>
31#include <babeltrace/ctf-ir/event-class.h>
32#include <babeltrace/ctf-ir/stream.h>
33#include <babeltrace/ctf-ir/stream-class.h>
ac0c6bdd 34#include <babeltrace/ctf-ir/clock-class.h>
bc506aa5
JD
35#include <babeltrace/ctf-ir/fields.h>
36#include <babeltrace/ctf-writer/stream-class.h>
37#include <babeltrace/ctf-writer/stream.h>
f3168545 38#include <assert.h>
bc506aa5 39
91b73004
JD
40#include <ctfcopytrace.h>
41
bc506aa5
JD
42#include "writer.h"
43
a619fcb7
JD
44static
45void unref_stream_class(struct bt_ctf_stream_class *writer_stream_class)
46{
47 bt_put(writer_stream_class);
48}
49
50static
51void unref_stream(struct bt_ctf_stream_class *writer_stream)
52{
53 bt_put(writer_stream);
54}
55
56gboolean empty_ht(gpointer key, gpointer value, gpointer user_data)
57{
58 return TRUE;
59}
60
cdcf612f
JD
61void destroy_stream_state_key(gpointer key)
62{
63 g_free((enum fs_writer_stream_state *) key);
64}
65
f3168545
JD
66static
67void trace_is_static_listener(struct bt_ctf_trace *trace, void *data)
68{
69 *((int *) data) = 1;
70}
71
bc506aa5 72static
91b73004
JD
73struct bt_ctf_stream_class *insert_new_stream_class(
74 struct writer_component *writer_component,
a619fcb7 75 struct fs_writer *fs_writer,
91b73004 76 struct bt_ctf_stream_class *stream_class)
bc506aa5 77{
b2f1f465 78 struct bt_ctf_stream_class *writer_stream_class = NULL;
9ae49d3d 79 struct bt_ctf_trace *trace = NULL, *writer_trace = NULL;
a619fcb7 80 struct bt_ctf_writer *ctf_writer = fs_writer->writer;
3241bc18 81 enum bt_component_status ret;
bc506aa5 82
3241bc18
JD
83 trace = bt_ctf_stream_class_get_trace(stream_class);
84 if (!trace) {
91b73004
JD
85 fprintf(writer_component->err,
86 "[error] %s in %s:%d\n", __func__, __FILE__,
bc506aa5 87 __LINE__);
9ae49d3d 88 goto error;
bc506aa5
JD
89 }
90
91b73004
JD
91 writer_trace = bt_ctf_writer_get_trace(ctf_writer);
92 if (!writer_trace) {
91b73004
JD
93 fprintf(writer_component->err,
94 "[error] %s in %s:%d\n", __func__, __FILE__,
d00b90bf 95 __LINE__);
9ae49d3d 96 goto error;
bc506aa5
JD
97 }
98
91b73004
JD
99 ret = ctf_copy_clock_classes(writer_component->err, writer_trace,
100 writer_stream_class, trace);
bc506aa5 101 if (ret != BT_COMPONENT_STATUS_OK) {
91b73004
JD
102 fprintf(writer_component->err,
103 "[error] %s in %s:%d\n", __func__, __FILE__,
bc506aa5 104 __LINE__);
9ae49d3d 105 goto error;
b2f1f465
JD
106 }
107
108 writer_stream_class = ctf_copy_stream_class(writer_component->err,
109 stream_class, writer_trace, true);
110 if (!writer_stream_class) {
111 fprintf(writer_component->err, "[error] Failed to copy stream class\n");
112 fprintf(writer_component->err, "[error] %s in %s:%d\n",
113 __func__, __FILE__, __LINE__);
9ae49d3d 114 goto error;
bc506aa5 115 }
bc506aa5 116
a619fcb7 117 g_hash_table_insert(fs_writer->stream_class_map,
bc506aa5
JD
118 (gpointer) stream_class, writer_stream_class);
119
9ae49d3d
JD
120 goto end;
121
122error:
123 BT_PUT(writer_stream_class);
124end:
b2f1f465 125 bt_put(writer_trace);
b2f1f465 126 bt_put(trace);
bc506aa5
JD
127 return writer_stream_class;
128}
129
2881e5b5
JD
130static
131enum fs_writer_stream_state *insert_new_stream_state(
132 struct writer_component *writer_component,
133 struct fs_writer *fs_writer, struct bt_ctf_stream *stream)
134{
135 enum fs_writer_stream_state *v = NULL;
136
137 v = g_new0(enum fs_writer_stream_state, 1);
138 if (!v) {
139 fprintf(writer_component->err,
140 "[error] %s in %s:%d\n", __func__,
141 __FILE__, __LINE__);
142 }
143 *v = FS_WRITER_UNKNOWN_STREAM;
144
145 g_hash_table_insert(fs_writer->stream_states, stream, v);
146
147 return v;
148}
149
bc506aa5 150static
f3168545 151struct fs_writer *insert_new_writer(
bc506aa5
JD
152 struct writer_component *writer_component,
153 struct bt_ctf_trace *trace)
154{
9ae49d3d
JD
155 struct bt_ctf_writer *ctf_writer = NULL;
156 struct bt_ctf_trace *writer_trace = NULL;
bc506aa5
JD
157 char trace_name[PATH_MAX];
158 enum bt_component_status ret;
cdcf612f
JD
159 struct bt_ctf_stream *stream = NULL;
160 struct fs_writer *fs_writer = NULL;
161 int nr_stream, i;
bc506aa5 162
9ae49d3d 163 /* FIXME: replace with trace name when it will work. */
bc506aa5 164 snprintf(trace_name, PATH_MAX, "%s/%s_%03d",
9057f037
JD
165 writer_component->base_path->str,
166 writer_component->trace_name_base->str,
bc506aa5
JD
167 writer_component->trace_id++);
168 printf_verbose("CTF-Writer creating trace in %s\n", trace_name);
9057f037 169
bc506aa5
JD
170 ctf_writer = bt_ctf_writer_create(trace_name);
171 if (!ctf_writer) {
172 fprintf(writer_component->err, "[error] %s in %s:%d\n",
173 __func__, __FILE__, __LINE__);
9ae49d3d 174 goto error;
bc506aa5
JD
175 }
176
91b73004
JD
177 writer_trace = bt_ctf_writer_get_trace(ctf_writer);
178 if (!writer_trace) {
91b73004
JD
179 fprintf(writer_component->err,
180 "[error] %s in %s:%d\n", __func__, __FILE__,
181 __LINE__);
9ae49d3d 182 goto error;
91b73004
JD
183 }
184
185 ret = ctf_copy_trace(writer_component->err, trace, writer_trace);
bc506aa5
JD
186 if (ret != BT_COMPONENT_STATUS_OK) {
187 fprintf(writer_component->err, "[error] Failed to copy trace\n");
188 fprintf(writer_component->err, "[error] %s in %s:%d\n",
189 __func__, __FILE__, __LINE__);
190 BT_PUT(ctf_writer);
f3168545 191 goto error;
bc506aa5 192 }
f3168545
JD
193
194 fs_writer = g_new0(struct fs_writer, 1);
195 if (!fs_writer) {
196 fprintf(writer_component->err,
197 "[error] %s in %s:%d\n", __func__, __FILE__,
198 __LINE__);
199 goto error;
200 }
201 fs_writer->writer = ctf_writer;
cdcf612f
JD
202 fs_writer->trace = trace;
203 fs_writer->writer_trace = writer_trace;
204 BT_PUT(writer_trace);
a619fcb7
JD
205 fs_writer->stream_class_map = g_hash_table_new_full(g_direct_hash,
206 g_direct_equal, NULL, (GDestroyNotify) unref_stream_class);
207 fs_writer->stream_map = g_hash_table_new_full(g_direct_hash,
208 g_direct_equal, NULL, (GDestroyNotify) unref_stream);
cdcf612f
JD
209 fs_writer->stream_states = g_hash_table_new_full(g_direct_hash,
210 g_direct_equal, NULL, destroy_stream_state_key);
211
212 /* Set all the existing streams in the unknown state. */
213 nr_stream = bt_ctf_trace_get_stream_count(trace);
214 for (i = 0; i < nr_stream; i++) {
cdcf612f
JD
215 stream = bt_ctf_trace_get_stream_by_index(trace, i);
216 if (!stream) {
217 fprintf(writer_component->err,
218 "[error] %s in %s:%d\n", __func__,
219 __FILE__, __LINE__);
220 goto error;
221 }
2881e5b5 222 insert_new_stream_state(writer_component, fs_writer, stream);
cdcf612f
JD
223 BT_PUT(stream);
224 }
225
226 /* Check if the trace is already static or register a listener. */
f3168545
JD
227 if (bt_ctf_trace_is_static(trace)) {
228 fs_writer->trace_static = 1;
229 fs_writer->static_listener_id = -1;
230 } else {
231 ret = bt_ctf_trace_add_is_static_listener(trace,
232 trace_is_static_listener, &fs_writer->trace_static);
233 if (ret < 0) {
234 fprintf(writer_component->err,
235 "[error] %s in %s:%d\n", __func__, __FILE__,
236 __LINE__);
f3168545
JD
237 goto error;
238 }
239 fs_writer->static_listener_id = ret;
240 }
bc506aa5
JD
241
242 g_hash_table_insert(writer_component->trace_map, (gpointer) trace,
f3168545 243 fs_writer);
bc506aa5 244
9ae49d3d
JD
245 goto end;
246
247error:
cdcf612f
JD
248 g_free(fs_writer);
249 fs_writer = NULL;
9ae49d3d 250 bt_put(writer_trace);
cdcf612f 251 bt_put(stream);
9ae49d3d 252 BT_PUT(ctf_writer);
bc506aa5 253end:
f3168545 254 return fs_writer;
bc506aa5
JD
255}
256
257static
f3168545 258struct fs_writer *get_fs_writer(struct writer_component *writer_component,
bc506aa5
JD
259 struct bt_ctf_stream_class *stream_class)
260{
9ae49d3d 261 struct bt_ctf_trace *trace = NULL;
f3168545 262 struct fs_writer *fs_writer;
bc506aa5
JD
263
264 trace = bt_ctf_stream_class_get_trace(stream_class);
265 if (!trace) {
bc506aa5
JD
266 fprintf(writer_component->err, "[error] %s in %s:%d\n",
267 __func__, __FILE__, __LINE__);
9ae49d3d 268 goto error;
bc506aa5
JD
269 }
270
f3168545 271 fs_writer = g_hash_table_lookup(writer_component->trace_map,
bc506aa5 272 (gpointer) trace);
f3168545
JD
273 if (!fs_writer) {
274 fs_writer = insert_new_writer(writer_component, trace);
bc506aa5 275 }
9ae49d3d
JD
276 BT_PUT(trace);
277 goto end;
bc506aa5 278
9ae49d3d 279error:
f3168545 280 fs_writer = NULL;
bc506aa5 281end:
f3168545 282 return fs_writer;
bc506aa5
JD
283}
284
a619fcb7
JD
285static
286struct fs_writer *get_fs_writer_from_stream(
287 struct writer_component *writer_component,
288 struct bt_ctf_stream *stream)
289{
290 struct bt_ctf_stream_class *stream_class = NULL;
291 struct fs_writer *fs_writer;
292
293 stream_class = bt_ctf_stream_get_class(stream);
294 if (!stream_class) {
295 fprintf(writer_component->err, "[error] %s in %s:%d\n",
296 __func__, __FILE__, __LINE__);
297 goto error;
298 }
299
300 fs_writer = get_fs_writer(writer_component, stream_class);
301 goto end;
302
303error:
304 fs_writer = NULL;
305
306end:
307 bt_put(stream_class);
308 return fs_writer;
309}
310
311static
312struct bt_ctf_stream_class *lookup_stream_class(
313 struct writer_component *writer_component,
314 struct bt_ctf_stream_class *stream_class)
315{
316 struct fs_writer *fs_writer = get_fs_writer(
317 writer_component, stream_class);
318 assert(fs_writer);
319 return (struct bt_ctf_stream_class *) g_hash_table_lookup(
320 fs_writer->stream_class_map, (gpointer) stream_class);
321}
322
323static
324struct bt_ctf_stream *lookup_stream(struct writer_component *writer_component,
325 struct bt_ctf_stream *stream)
326{
327 struct fs_writer *fs_writer = get_fs_writer_from_stream(
328 writer_component, stream);
329 assert(fs_writer);
330 return (struct bt_ctf_stream *) g_hash_table_lookup(
331 fs_writer->stream_map, (gpointer) stream);
332}
333
334static
335struct bt_ctf_stream *insert_new_stream(
336 struct writer_component *writer_component,
337 struct fs_writer *fs_writer,
338 struct bt_ctf_stream_class *stream_class,
339 struct bt_ctf_stream *stream)
340{
341 struct bt_ctf_stream *writer_stream = NULL;
342 struct bt_ctf_stream_class *writer_stream_class = NULL;
343 struct bt_ctf_writer *ctf_writer = bt_get(fs_writer->writer);
344
345 writer_stream_class = lookup_stream_class(writer_component,
346 stream_class);
347 if (!writer_stream_class) {
348 writer_stream_class = insert_new_stream_class(
349 writer_component, fs_writer, stream_class);
350 if (!writer_stream_class) {
351 fprintf(writer_component->err, "[error] %s in %s:%d\n",
352 __func__, __FILE__, __LINE__);
353 goto error;
354 }
355 }
356 bt_get(writer_stream_class);
357
358 writer_stream = bt_ctf_writer_create_stream(ctf_writer,
359 writer_stream_class);
360 if (!writer_stream) {
361 fprintf(writer_component->err, "[error] %s in %s:%d\n",
362 __func__, __FILE__, __LINE__);
363 goto error;
364 }
365
366 g_hash_table_insert(fs_writer->stream_map, (gpointer) stream,
367 writer_stream);
368
369 goto end;
370
371error:
372 BT_PUT(writer_stream);
373end:
374 bt_put(ctf_writer);
375 bt_put(writer_stream_class);
376 return writer_stream;
377}
378
379static
380struct bt_ctf_event_class *get_event_class(struct writer_component *writer_component,
381 struct bt_ctf_stream_class *writer_stream_class,
382 struct bt_ctf_event_class *event_class)
383{
384 return bt_ctf_stream_class_get_event_class_by_id(writer_stream_class,
385 bt_ctf_event_class_get_id(event_class));
386}
387
bc506aa5
JD
388static
389struct bt_ctf_stream *get_writer_stream(
390 struct writer_component *writer_component,
391 struct bt_ctf_packet *packet, struct bt_ctf_stream *stream)
392{
9ae49d3d 393 struct bt_ctf_stream *writer_stream = NULL;
bc506aa5 394
f384901f
JD
395 writer_stream = lookup_stream(writer_component, stream);
396 if (!writer_stream) {
bc506aa5
JD
397 fprintf(writer_component->err, "[error] %s in %s:%d\n",
398 __func__, __FILE__, __LINE__);
9ae49d3d 399 goto error;
bc506aa5 400 }
9ae49d3d
JD
401 bt_get(writer_stream);
402
403 goto end;
bc506aa5 404
9ae49d3d
JD
405error:
406 BT_PUT(writer_stream);
407end:
bc506aa5
JD
408 return writer_stream;
409}
410
f3168545 411BT_HIDDEN
a619fcb7
JD
412void writer_close(struct writer_component *writer_component,
413 struct fs_writer *fs_writer)
f3168545 414{
f3168545 415 if (fs_writer->static_listener_id > 0) {
a619fcb7 416 bt_ctf_trace_remove_is_static_listener(fs_writer->trace,
f3168545
JD
417 fs_writer->static_listener_id);
418 }
a619fcb7
JD
419
420 /* Empty the stream class HT. */
421 g_hash_table_foreach_remove(fs_writer->stream_class_map,
422 empty_ht, NULL);
423 g_hash_table_destroy(fs_writer->stream_class_map);
424
425 /* Empty the stream HT. */
426 g_hash_table_foreach_remove(fs_writer->stream_map,
427 empty_ht, NULL);
428 g_hash_table_destroy(fs_writer->stream_map);
cdcf612f
JD
429
430 /* Empty the stream state HT. */
431 g_hash_table_foreach_remove(fs_writer->stream_states,
432 empty_ht, NULL);
433 g_hash_table_destroy(fs_writer->stream_states);
f3168545
JD
434}
435
f384901f
JD
436BT_HIDDEN
437enum bt_component_status writer_stream_begin(
438 struct writer_component *writer_component,
439 struct bt_ctf_stream *stream)
440{
441 struct bt_ctf_stream_class *stream_class = NULL;
442 struct fs_writer *fs_writer;
f384901f
JD
443 struct bt_ctf_stream *writer_stream = NULL;
444 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
cdcf612f 445 enum fs_writer_stream_state *state;
f384901f
JD
446
447 stream_class = bt_ctf_stream_get_class(stream);
448 if (!stream_class) {
449 fprintf(writer_component->err, "[error] %s in %s:%d\n",
450 __func__, __FILE__, __LINE__);
451 goto error;
452 }
453
454 fs_writer = get_fs_writer(writer_component, stream_class);
455 if (!fs_writer) {
456 fprintf(writer_component->err, "[error] %s in %s:%d\n",
457 __func__, __FILE__, __LINE__);
458 goto error;
459 }
cdcf612f
JD
460
461 /* Set the stream as active */
462 state = g_hash_table_lookup(fs_writer->stream_states, stream);
2881e5b5
JD
463 if (!state) {
464 if (fs_writer->trace_static) {
465 fprintf(writer_component->err, "[error] Adding a new "
466 "stream on a static trace\n");
467 goto error;
468 }
469 state = insert_new_stream_state(writer_component, fs_writer,
470 stream);
471 }
cdcf612f
JD
472 if (*state != FS_WRITER_UNKNOWN_STREAM) {
473 fprintf(writer_component->err, "[error] Unexpected stream "
474 "state %d\n", *state);
475 goto error;
476 }
477 *state = FS_WRITER_ACTIVE_STREAM;
478
a619fcb7 479 writer_stream = insert_new_stream(writer_component, fs_writer,
f384901f
JD
480 stream_class, stream);
481 if (!writer_stream) {
482 fprintf(writer_component->err, "[error] %s in %s:%d\n",
483 __func__, __FILE__, __LINE__);
484 goto error;
485 }
486 fs_writer->active_streams++;
487
488 goto end;
489
490error:
491 ret = BT_COMPONENT_STATUS_ERROR;
492end:
f384901f
JD
493 bt_put(stream_class);
494 return ret;
495}
496
cdcf612f
JD
497void check_completed_trace(gpointer key, gpointer value, gpointer user_data)
498{
499 enum fs_writer_stream_state *state = value;
500 int *trace_completed = user_data;
501
502 if (*state != FS_WRITER_COMPLETED_STREAM) {
503 *trace_completed = 0;
504 }
505}
506
f3168545
JD
507BT_HIDDEN
508enum bt_component_status writer_stream_end(
509 struct writer_component *writer_component,
510 struct bt_ctf_stream *stream)
511{
512 struct bt_ctf_stream_class *stream_class = NULL;
513 struct fs_writer *fs_writer;
514 struct bt_ctf_trace *trace = NULL;
515 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
cdcf612f 516 enum fs_writer_stream_state *state;
f3168545 517
f3168545
JD
518 stream_class = bt_ctf_stream_get_class(stream);
519 if (!stream_class) {
520 fprintf(writer_component->err, "[error] %s in %s:%d\n",
521 __func__, __FILE__, __LINE__);
522 goto error;
523 }
524
525 fs_writer = get_fs_writer(writer_component, stream_class);
526 if (!fs_writer) {
527 fprintf(writer_component->err, "[error] %s in %s:%d\n",
528 __func__, __FILE__, __LINE__);
529 goto error;
530 }
cdcf612f
JD
531
532 state = g_hash_table_lookup(fs_writer->stream_states, stream);
533 if (*state != FS_WRITER_ACTIVE_STREAM) {
534 fprintf(writer_component->err, "[error] Unexpected stream "
535 "state %d\n", *state);
536 goto error;
537 }
538 *state = FS_WRITER_COMPLETED_STREAM;
539
a619fcb7 540 g_hash_table_remove(fs_writer->stream_map, stream);
f3168545 541
cdcf612f
JD
542 if (fs_writer->trace_static) {
543 int trace_completed = 1;
544
545 g_hash_table_foreach(fs_writer->stream_states,
546 check_completed_trace, &trace_completed);
547 if (trace_completed) {
548 writer_close(writer_component, fs_writer);
549 g_hash_table_remove(writer_component->trace_map,
550 fs_writer->trace);
551 }
f3168545
JD
552 }
553
554 goto end;
555
556error:
557 ret = BT_COMPONENT_STATUS_ERROR;
558end:
559 BT_PUT(trace);
560 BT_PUT(stream_class);
561 return ret;
562}
563
bc506aa5
JD
564BT_HIDDEN
565enum bt_component_status writer_new_packet(
566 struct writer_component *writer_component,
567 struct bt_ctf_packet *packet)
568{
9ae49d3d
JD
569 struct bt_ctf_stream *stream = NULL, *writer_stream = NULL;
570 struct bt_ctf_field *writer_packet_context = NULL;
bc506aa5 571 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
b2f1f465 572 int int_ret;
bc506aa5
JD
573
574 stream = bt_ctf_packet_get_stream(packet);
575 if (!stream) {
bc506aa5
JD
576 fprintf(writer_component->err, "[error] %s in %s:%d\n",
577 __func__, __FILE__, __LINE__);
9ae49d3d 578 goto error;
bc506aa5
JD
579 }
580
bc506aa5
JD
581 writer_stream = get_writer_stream(writer_component, packet, stream);
582 if (!writer_stream) {
bc506aa5
JD
583 fprintf(writer_component->err, "[error] %s in %s:%d\n",
584 __func__, __FILE__, __LINE__);
9ae49d3d 585 goto error;
bc506aa5 586 }
9ae49d3d 587 BT_PUT(stream);
bc506aa5 588
b2f1f465 589 writer_packet_context = ctf_copy_packet_context(writer_component->err,
ab80adac 590 packet, writer_stream, 1);
b2f1f465 591 if (!writer_packet_context) {
91b73004
JD
592 fprintf(writer_component->err, "[error] %s in %s:%d\n",
593 __func__, __FILE__, __LINE__);
9ae49d3d 594 goto error;
bc506aa5
JD
595 }
596
b2f1f465
JD
597 int_ret = bt_ctf_stream_set_packet_context(writer_stream,
598 writer_packet_context);
599 if (int_ret < 0) {
b2f1f465
JD
600 fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__,
601 __FILE__, __LINE__);
9ae49d3d 602 goto error;
b2f1f465 603 }
9ae49d3d
JD
604 BT_PUT(writer_stream);
605 BT_PUT(writer_packet_context);
b2f1f465 606
9ae49d3d 607 goto end;
bc506aa5 608
9ae49d3d
JD
609error:
610 ret = BT_COMPONENT_STATUS_ERROR;
611end:
612 bt_put(writer_stream);
b2f1f465 613 bt_put(writer_packet_context);
91b73004 614 bt_put(stream);
bc506aa5
JD
615 return ret;
616}
617
618BT_HIDDEN
619enum bt_component_status writer_close_packet(
620 struct writer_component *writer_component,
621 struct bt_ctf_packet *packet)
622{
9ae49d3d 623 struct bt_ctf_stream *stream = NULL, *writer_stream = NULL;
bc506aa5
JD
624 enum bt_component_status ret;
625
626 stream = bt_ctf_packet_get_stream(packet);
627 if (!stream) {
bc506aa5
JD
628 fprintf(writer_component->err, "[error] %s in %s:%d\n",
629 __func__, __FILE__, __LINE__);
9ae49d3d 630 goto error;
bc506aa5
JD
631 }
632
633 writer_stream = lookup_stream(writer_component, stream);
634 if (!writer_stream) {
bc506aa5
JD
635 fprintf(writer_component->err, "[error] %s in %s:%d\n",
636 __func__, __FILE__, __LINE__);
9ae49d3d 637 goto error;
bc506aa5 638 }
9ae49d3d 639 BT_PUT(stream);
bc506aa5 640
9ae49d3d 641 bt_get(writer_stream);
bc506aa5 642
bc506aa5
JD
643 ret = bt_ctf_stream_flush(writer_stream);
644 if (ret < 0) {
645 fprintf(writer_component->err,
646 "[error] Failed to flush packet\n");
9ae49d3d 647 goto error;
bc506aa5 648 }
9ae49d3d 649 BT_PUT(writer_stream);
bc506aa5
JD
650
651 ret = BT_COMPONENT_STATUS_OK;
9ae49d3d 652 goto end;
bc506aa5 653
9ae49d3d
JD
654error:
655 ret = BT_COMPONENT_STATUS_ERROR;
656end:
bc506aa5 657 bt_put(writer_stream);
bc506aa5 658 bt_put(stream);
bc506aa5
JD
659 return ret;
660}
661
bc506aa5
JD
662BT_HIDDEN
663enum bt_component_status writer_output_event(
664 struct writer_component *writer_component,
665 struct bt_ctf_event *event)
666{
667 enum bt_component_status ret;
9ae49d3d
JD
668 struct bt_ctf_event_class *event_class = NULL, *writer_event_class = NULL;
669 struct bt_ctf_stream *stream = NULL, *writer_stream = NULL;
670 struct bt_ctf_stream_class *stream_class = NULL, *writer_stream_class = NULL;
671 struct bt_ctf_event *writer_event = NULL;
bc506aa5
JD
672 const char *event_name;
673 int int_ret;
674
675 event_class = bt_ctf_event_get_class(event);
676 if (!event_class) {
bc506aa5
JD
677 fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__,
678 __FILE__, __LINE__);
9ae49d3d 679 goto error;
bc506aa5
JD
680 }
681
682 event_name = bt_ctf_event_class_get_name(event_class);
683 if (!event_name) {
bc506aa5
JD
684 fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__,
685 __FILE__, __LINE__);
9ae49d3d 686 goto error;
bc506aa5 687 }
bc506aa5
JD
688
689 stream = bt_ctf_event_get_stream(event);
690 if (!stream) {
bc506aa5
JD
691 fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__,
692 __FILE__, __LINE__);
9ae49d3d 693 goto error;
bc506aa5
JD
694 }
695
696 writer_stream = lookup_stream(writer_component, stream);
697 if (!writer_stream || !bt_get(writer_stream)) {
bc506aa5
JD
698 fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__,
699 __FILE__, __LINE__);
9ae49d3d 700 goto error;
bc506aa5
JD
701 }
702
703 stream_class = bt_ctf_event_class_get_stream_class(event_class);
704 if (!stream_class) {
bc506aa5
JD
705 fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__,
706 __FILE__, __LINE__);
9ae49d3d 707 goto error;
bc506aa5
JD
708 }
709
a619fcb7 710 writer_stream_class = lookup_stream_class(writer_component, stream_class);
bc506aa5 711 if (!writer_stream_class || !bt_get(writer_stream_class)) {
bc506aa5
JD
712 fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__,
713 __FILE__, __LINE__);
9ae49d3d 714 goto error;
bc506aa5
JD
715 }
716
717 writer_event_class = get_event_class(writer_component,
718 writer_stream_class, event_class);
719 if (!writer_event_class) {
af34e875
JD
720 writer_event_class = ctf_copy_event_class(writer_component->err,
721 event_class);
722 if (!writer_event_class) {
af34e875
JD
723 fprintf(writer_component->err, "[error] %s in %s:%d\n",
724 __func__, __FILE__, __LINE__);
9ae49d3d 725 goto error;
af34e875
JD
726 }
727 int_ret = bt_ctf_stream_class_add_event_class(
728 writer_stream_class, writer_event_class);
729 if (int_ret) {
af34e875
JD
730 fprintf(writer_component->err, "[error] %s in %s:%d\n",
731 __func__, __FILE__, __LINE__);
9ae49d3d 732 goto error;
af34e875 733 }
bc506aa5
JD
734 }
735
b2f1f465
JD
736 writer_event = ctf_copy_event(writer_component->err, event,
737 writer_event_class, true);
bc506aa5 738 if (!writer_event) {
bc506aa5
JD
739 fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__,
740 __FILE__, __LINE__);
741 fprintf(writer_component->err, "[error] Failed to copy event %s\n",
742 bt_ctf_event_class_get_name(writer_event_class));
9ae49d3d 743 goto error;
bc506aa5
JD
744 }
745
746 int_ret = bt_ctf_stream_append_event(writer_stream, writer_event);
747 if (int_ret < 0) {
bc506aa5
JD
748 fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__,
749 __FILE__, __LINE__);
750 fprintf(writer_component->err, "[error] Failed to append event %s\n",
751 bt_ctf_event_class_get_name(writer_event_class));
9ae49d3d 752 goto error;
bc506aa5
JD
753 }
754
755 ret = BT_COMPONENT_STATUS_OK;
9ae49d3d 756 goto end;
bc506aa5 757
9ae49d3d
JD
758error:
759 ret = BT_COMPONENT_STATUS_ERROR;
760end:
bc506aa5 761 bt_put(writer_event);
bc506aa5 762 bt_put(writer_event_class);
bc506aa5 763 bt_put(writer_stream_class);
bc506aa5 764 bt_put(stream_class);
bc506aa5 765 bt_put(writer_stream);
bc506aa5 766 bt_put(stream);
bc506aa5 767 bt_put(event_class);
bc506aa5
JD
768 return ret;
769}
This page took 0.0833 seconds and 4 git commands to generate.