fs-sink: useless active_stream member
[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
2e4636e1
JD
61gboolean empty_streams_ht(gpointer key, gpointer value, gpointer user_data)
62{
63 struct bt_ctf_stream *writer_stream = value;
64
65 bt_ctf_stream_flush(writer_stream);
66
67 return TRUE;
68}
69
cdcf612f
JD
70void destroy_stream_state_key(gpointer key)
71{
72 g_free((enum fs_writer_stream_state *) key);
73}
74
6f25f7c4
JD
75void check_completed_trace(gpointer key, gpointer value, gpointer user_data)
76{
77 enum fs_writer_stream_state *state = value;
78 int *trace_completed = user_data;
79
80 if (*state != FS_WRITER_COMPLETED_STREAM) {
81 *trace_completed = 0;
82 }
83}
84
f3168545
JD
85static
86void trace_is_static_listener(struct bt_ctf_trace *trace, void *data)
87{
6f25f7c4
JD
88 struct fs_writer *fs_writer = data;
89 int trace_completed = 1;
90
91 fs_writer->trace_static = 1;
92
93 g_hash_table_foreach(fs_writer->stream_states,
94 check_completed_trace, &trace_completed);
95 if (trace_completed) {
96 writer_close(fs_writer->writer_component, fs_writer);
97 g_hash_table_remove(fs_writer->writer_component->trace_map,
98 fs_writer->trace);
99 }
f3168545
JD
100}
101
bc506aa5 102static
91b73004
JD
103struct bt_ctf_stream_class *insert_new_stream_class(
104 struct writer_component *writer_component,
a619fcb7 105 struct fs_writer *fs_writer,
91b73004 106 struct bt_ctf_stream_class *stream_class)
bc506aa5 107{
b2f1f465 108 struct bt_ctf_stream_class *writer_stream_class = NULL;
9ae49d3d 109 struct bt_ctf_trace *trace = NULL, *writer_trace = NULL;
a619fcb7 110 struct bt_ctf_writer *ctf_writer = fs_writer->writer;
3241bc18 111 enum bt_component_status ret;
bc506aa5 112
3241bc18
JD
113 trace = bt_ctf_stream_class_get_trace(stream_class);
114 if (!trace) {
91b73004
JD
115 fprintf(writer_component->err,
116 "[error] %s in %s:%d\n", __func__, __FILE__,
bc506aa5 117 __LINE__);
9ae49d3d 118 goto error;
bc506aa5
JD
119 }
120
91b73004
JD
121 writer_trace = bt_ctf_writer_get_trace(ctf_writer);
122 if (!writer_trace) {
91b73004
JD
123 fprintf(writer_component->err,
124 "[error] %s in %s:%d\n", __func__, __FILE__,
d00b90bf 125 __LINE__);
9ae49d3d 126 goto error;
bc506aa5
JD
127 }
128
91b73004
JD
129 ret = ctf_copy_clock_classes(writer_component->err, writer_trace,
130 writer_stream_class, trace);
bc506aa5 131 if (ret != BT_COMPONENT_STATUS_OK) {
91b73004
JD
132 fprintf(writer_component->err,
133 "[error] %s in %s:%d\n", __func__, __FILE__,
bc506aa5 134 __LINE__);
9ae49d3d 135 goto error;
b2f1f465
JD
136 }
137
138 writer_stream_class = ctf_copy_stream_class(writer_component->err,
139 stream_class, writer_trace, true);
140 if (!writer_stream_class) {
141 fprintf(writer_component->err, "[error] Failed to copy stream class\n");
142 fprintf(writer_component->err, "[error] %s in %s:%d\n",
143 __func__, __FILE__, __LINE__);
9ae49d3d 144 goto error;
bc506aa5 145 }
bc506aa5 146
a619fcb7 147 g_hash_table_insert(fs_writer->stream_class_map,
bc506aa5
JD
148 (gpointer) stream_class, writer_stream_class);
149
9ae49d3d
JD
150 goto end;
151
152error:
153 BT_PUT(writer_stream_class);
154end:
b2f1f465 155 bt_put(writer_trace);
b2f1f465 156 bt_put(trace);
bc506aa5
JD
157 return writer_stream_class;
158}
159
2881e5b5
JD
160static
161enum fs_writer_stream_state *insert_new_stream_state(
162 struct writer_component *writer_component,
163 struct fs_writer *fs_writer, struct bt_ctf_stream *stream)
164{
165 enum fs_writer_stream_state *v = NULL;
166
167 v = g_new0(enum fs_writer_stream_state, 1);
168 if (!v) {
169 fprintf(writer_component->err,
170 "[error] %s in %s:%d\n", __func__,
171 __FILE__, __LINE__);
172 }
173 *v = FS_WRITER_UNKNOWN_STREAM;
174
175 g_hash_table_insert(fs_writer->stream_states, stream, v);
176
177 return v;
178}
179
9b4f54fb
JD
180static
181int make_trace_path(struct writer_component *writer_component,
182 struct bt_ctf_trace *trace, char *trace_path)
183{
184 int ret;
185 const char *trace_name;
186
187 trace_name = bt_ctf_trace_get_name(trace);
188 if (!trace_name) {
189 trace_name = writer_component->trace_name_base->str;
190 }
191 /* XXX: we might have to skip the first level, TBD. */
192
193 /* Sanitize the trace name. */
194 if (strlen(trace_name) == 2 && !strcmp(trace_name, "..")) {
195 fprintf(writer_component->err, "[error] Trace name cannot "
196 "be \"..\"\n");
197 goto error;
198 }
199
200 if (strstr(trace_name, "../")) {
201 fprintf(writer_component->err, "[error] Trace name cannot "
202 "contain \"../\", received \"%s\"\n",
203 trace_name);
204 goto error;
205
206 }
207
208 snprintf(trace_path, PATH_MAX, "%s/%s",
209 writer_component->base_path->str,
210 trace_name);
211 if (g_file_test(trace_path, G_FILE_TEST_EXISTS)) {
212 int i = 0;
213 do {
214 snprintf(trace_path, PATH_MAX, "%s/%s-%d",
215 writer_component->base_path->str,
216 trace_name, ++i);
217 } while (g_file_test(trace_path, G_FILE_TEST_EXISTS) && i < INT_MAX);
218 if (i == INT_MAX) {
219 fprintf(writer_component->err, "[error] Unable to find "
220 "a unique trace path\n");
221 goto error;
222 }
223 }
224
225 ret = 0;
226
227 goto end;
228
229error:
230 ret = -1;
231end:
232 return ret;
233}
234
bc506aa5 235static
f3168545 236struct fs_writer *insert_new_writer(
bc506aa5
JD
237 struct writer_component *writer_component,
238 struct bt_ctf_trace *trace)
239{
9ae49d3d
JD
240 struct bt_ctf_writer *ctf_writer = NULL;
241 struct bt_ctf_trace *writer_trace = NULL;
9b4f54fb 242 char trace_path[PATH_MAX];
bc506aa5 243 enum bt_component_status ret;
cdcf612f
JD
244 struct bt_ctf_stream *stream = NULL;
245 struct fs_writer *fs_writer = NULL;
246 int nr_stream, i;
bc506aa5 247
9b4f54fb
JD
248 ret = make_trace_path(writer_component, trace, trace_path);
249 if (ret) {
250 fprintf(writer_component->err, "[error] %s in %s:%d\n",
251 __func__, __FILE__, __LINE__);
252 goto error;
253 }
254
255 printf("ctf.fs sink creating trace in %s\n", trace_path);
9057f037 256
9b4f54fb 257 ctf_writer = bt_ctf_writer_create(trace_path);
bc506aa5
JD
258 if (!ctf_writer) {
259 fprintf(writer_component->err, "[error] %s in %s:%d\n",
260 __func__, __FILE__, __LINE__);
9ae49d3d 261 goto error;
bc506aa5
JD
262 }
263
91b73004
JD
264 writer_trace = bt_ctf_writer_get_trace(ctf_writer);
265 if (!writer_trace) {
91b73004
JD
266 fprintf(writer_component->err,
267 "[error] %s in %s:%d\n", __func__, __FILE__,
268 __LINE__);
9ae49d3d 269 goto error;
91b73004
JD
270 }
271
272 ret = ctf_copy_trace(writer_component->err, trace, writer_trace);
bc506aa5
JD
273 if (ret != BT_COMPONENT_STATUS_OK) {
274 fprintf(writer_component->err, "[error] Failed to copy trace\n");
275 fprintf(writer_component->err, "[error] %s in %s:%d\n",
276 __func__, __FILE__, __LINE__);
277 BT_PUT(ctf_writer);
f3168545 278 goto error;
bc506aa5 279 }
f3168545
JD
280
281 fs_writer = g_new0(struct fs_writer, 1);
282 if (!fs_writer) {
283 fprintf(writer_component->err,
284 "[error] %s in %s:%d\n", __func__, __FILE__,
285 __LINE__);
286 goto error;
287 }
288 fs_writer->writer = ctf_writer;
cdcf612f
JD
289 fs_writer->trace = trace;
290 fs_writer->writer_trace = writer_trace;
6f25f7c4 291 fs_writer->writer_component = writer_component;
cdcf612f 292 BT_PUT(writer_trace);
a619fcb7
JD
293 fs_writer->stream_class_map = g_hash_table_new_full(g_direct_hash,
294 g_direct_equal, NULL, (GDestroyNotify) unref_stream_class);
295 fs_writer->stream_map = g_hash_table_new_full(g_direct_hash,
296 g_direct_equal, NULL, (GDestroyNotify) unref_stream);
cdcf612f
JD
297 fs_writer->stream_states = g_hash_table_new_full(g_direct_hash,
298 g_direct_equal, NULL, destroy_stream_state_key);
299
300 /* Set all the existing streams in the unknown state. */
301 nr_stream = bt_ctf_trace_get_stream_count(trace);
302 for (i = 0; i < nr_stream; i++) {
cdcf612f
JD
303 stream = bt_ctf_trace_get_stream_by_index(trace, i);
304 if (!stream) {
305 fprintf(writer_component->err,
306 "[error] %s in %s:%d\n", __func__,
307 __FILE__, __LINE__);
308 goto error;
309 }
2881e5b5 310 insert_new_stream_state(writer_component, fs_writer, stream);
cdcf612f
JD
311 BT_PUT(stream);
312 }
313
314 /* Check if the trace is already static or register a listener. */
f3168545
JD
315 if (bt_ctf_trace_is_static(trace)) {
316 fs_writer->trace_static = 1;
317 fs_writer->static_listener_id = -1;
318 } else {
319 ret = bt_ctf_trace_add_is_static_listener(trace,
6f25f7c4 320 trace_is_static_listener, fs_writer);
f3168545
JD
321 if (ret < 0) {
322 fprintf(writer_component->err,
323 "[error] %s in %s:%d\n", __func__, __FILE__,
324 __LINE__);
f3168545
JD
325 goto error;
326 }
327 fs_writer->static_listener_id = ret;
328 }
bc506aa5
JD
329
330 g_hash_table_insert(writer_component->trace_map, (gpointer) trace,
f3168545 331 fs_writer);
bc506aa5 332
9ae49d3d
JD
333 goto end;
334
335error:
cdcf612f
JD
336 g_free(fs_writer);
337 fs_writer = NULL;
9ae49d3d 338 bt_put(writer_trace);
cdcf612f 339 bt_put(stream);
9ae49d3d 340 BT_PUT(ctf_writer);
bc506aa5 341end:
f3168545 342 return fs_writer;
bc506aa5
JD
343}
344
345static
f3168545 346struct fs_writer *get_fs_writer(struct writer_component *writer_component,
bc506aa5
JD
347 struct bt_ctf_stream_class *stream_class)
348{
9ae49d3d 349 struct bt_ctf_trace *trace = NULL;
f3168545 350 struct fs_writer *fs_writer;
bc506aa5
JD
351
352 trace = bt_ctf_stream_class_get_trace(stream_class);
353 if (!trace) {
bc506aa5
JD
354 fprintf(writer_component->err, "[error] %s in %s:%d\n",
355 __func__, __FILE__, __LINE__);
9ae49d3d 356 goto error;
bc506aa5
JD
357 }
358
f3168545 359 fs_writer = g_hash_table_lookup(writer_component->trace_map,
bc506aa5 360 (gpointer) trace);
f3168545
JD
361 if (!fs_writer) {
362 fs_writer = insert_new_writer(writer_component, trace);
bc506aa5 363 }
9ae49d3d
JD
364 BT_PUT(trace);
365 goto end;
bc506aa5 366
9ae49d3d 367error:
f3168545 368 fs_writer = NULL;
bc506aa5 369end:
f3168545 370 return fs_writer;
bc506aa5
JD
371}
372
a619fcb7
JD
373static
374struct fs_writer *get_fs_writer_from_stream(
375 struct writer_component *writer_component,
376 struct bt_ctf_stream *stream)
377{
378 struct bt_ctf_stream_class *stream_class = NULL;
379 struct fs_writer *fs_writer;
380
381 stream_class = bt_ctf_stream_get_class(stream);
382 if (!stream_class) {
383 fprintf(writer_component->err, "[error] %s in %s:%d\n",
384 __func__, __FILE__, __LINE__);
385 goto error;
386 }
387
388 fs_writer = get_fs_writer(writer_component, stream_class);
389 goto end;
390
391error:
392 fs_writer = NULL;
393
394end:
395 bt_put(stream_class);
396 return fs_writer;
397}
398
399static
400struct bt_ctf_stream_class *lookup_stream_class(
401 struct writer_component *writer_component,
402 struct bt_ctf_stream_class *stream_class)
403{
404 struct fs_writer *fs_writer = get_fs_writer(
405 writer_component, stream_class);
406 assert(fs_writer);
407 return (struct bt_ctf_stream_class *) g_hash_table_lookup(
408 fs_writer->stream_class_map, (gpointer) stream_class);
409}
410
411static
412struct bt_ctf_stream *lookup_stream(struct writer_component *writer_component,
413 struct bt_ctf_stream *stream)
414{
415 struct fs_writer *fs_writer = get_fs_writer_from_stream(
416 writer_component, stream);
417 assert(fs_writer);
418 return (struct bt_ctf_stream *) g_hash_table_lookup(
419 fs_writer->stream_map, (gpointer) stream);
420}
421
422static
423struct bt_ctf_stream *insert_new_stream(
424 struct writer_component *writer_component,
425 struct fs_writer *fs_writer,
426 struct bt_ctf_stream_class *stream_class,
427 struct bt_ctf_stream *stream)
428{
429 struct bt_ctf_stream *writer_stream = NULL;
430 struct bt_ctf_stream_class *writer_stream_class = NULL;
431 struct bt_ctf_writer *ctf_writer = bt_get(fs_writer->writer);
432
433 writer_stream_class = lookup_stream_class(writer_component,
434 stream_class);
435 if (!writer_stream_class) {
436 writer_stream_class = insert_new_stream_class(
437 writer_component, fs_writer, stream_class);
438 if (!writer_stream_class) {
439 fprintf(writer_component->err, "[error] %s in %s:%d\n",
440 __func__, __FILE__, __LINE__);
441 goto error;
442 }
443 }
444 bt_get(writer_stream_class);
445
446 writer_stream = bt_ctf_writer_create_stream(ctf_writer,
447 writer_stream_class);
448 if (!writer_stream) {
449 fprintf(writer_component->err, "[error] %s in %s:%d\n",
450 __func__, __FILE__, __LINE__);
451 goto error;
452 }
453
454 g_hash_table_insert(fs_writer->stream_map, (gpointer) stream,
455 writer_stream);
456
457 goto end;
458
459error:
460 BT_PUT(writer_stream);
461end:
462 bt_put(ctf_writer);
463 bt_put(writer_stream_class);
464 return writer_stream;
465}
466
467static
468struct bt_ctf_event_class *get_event_class(struct writer_component *writer_component,
469 struct bt_ctf_stream_class *writer_stream_class,
470 struct bt_ctf_event_class *event_class)
471{
472 return bt_ctf_stream_class_get_event_class_by_id(writer_stream_class,
473 bt_ctf_event_class_get_id(event_class));
474}
475
bc506aa5
JD
476static
477struct bt_ctf_stream *get_writer_stream(
478 struct writer_component *writer_component,
479 struct bt_ctf_packet *packet, struct bt_ctf_stream *stream)
480{
9ae49d3d 481 struct bt_ctf_stream *writer_stream = NULL;
bc506aa5 482
f384901f
JD
483 writer_stream = lookup_stream(writer_component, stream);
484 if (!writer_stream) {
bc506aa5
JD
485 fprintf(writer_component->err, "[error] %s in %s:%d\n",
486 __func__, __FILE__, __LINE__);
9ae49d3d 487 goto error;
bc506aa5 488 }
9ae49d3d
JD
489 bt_get(writer_stream);
490
491 goto end;
bc506aa5 492
9ae49d3d
JD
493error:
494 BT_PUT(writer_stream);
495end:
bc506aa5
JD
496 return writer_stream;
497}
498
f3168545 499BT_HIDDEN
a619fcb7
JD
500void writer_close(struct writer_component *writer_component,
501 struct fs_writer *fs_writer)
f3168545 502{
f3168545 503 if (fs_writer->static_listener_id > 0) {
a619fcb7 504 bt_ctf_trace_remove_is_static_listener(fs_writer->trace,
f3168545
JD
505 fs_writer->static_listener_id);
506 }
a619fcb7
JD
507
508 /* Empty the stream class HT. */
509 g_hash_table_foreach_remove(fs_writer->stream_class_map,
510 empty_ht, NULL);
511 g_hash_table_destroy(fs_writer->stream_class_map);
512
513 /* Empty the stream HT. */
514 g_hash_table_foreach_remove(fs_writer->stream_map,
2e4636e1 515 empty_streams_ht, NULL);
a619fcb7 516 g_hash_table_destroy(fs_writer->stream_map);
cdcf612f
JD
517
518 /* Empty the stream state HT. */
519 g_hash_table_foreach_remove(fs_writer->stream_states,
520 empty_ht, NULL);
521 g_hash_table_destroy(fs_writer->stream_states);
f3168545
JD
522}
523
f384901f
JD
524BT_HIDDEN
525enum bt_component_status writer_stream_begin(
526 struct writer_component *writer_component,
527 struct bt_ctf_stream *stream)
528{
529 struct bt_ctf_stream_class *stream_class = NULL;
530 struct fs_writer *fs_writer;
f384901f
JD
531 struct bt_ctf_stream *writer_stream = NULL;
532 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
cdcf612f 533 enum fs_writer_stream_state *state;
f384901f
JD
534
535 stream_class = bt_ctf_stream_get_class(stream);
536 if (!stream_class) {
537 fprintf(writer_component->err, "[error] %s in %s:%d\n",
538 __func__, __FILE__, __LINE__);
539 goto error;
540 }
541
542 fs_writer = get_fs_writer(writer_component, stream_class);
543 if (!fs_writer) {
544 fprintf(writer_component->err, "[error] %s in %s:%d\n",
545 __func__, __FILE__, __LINE__);
546 goto error;
547 }
cdcf612f
JD
548
549 /* Set the stream as active */
550 state = g_hash_table_lookup(fs_writer->stream_states, stream);
2881e5b5
JD
551 if (!state) {
552 if (fs_writer->trace_static) {
553 fprintf(writer_component->err, "[error] Adding a new "
554 "stream on a static trace\n");
555 goto error;
556 }
557 state = insert_new_stream_state(writer_component, fs_writer,
558 stream);
559 }
cdcf612f
JD
560 if (*state != FS_WRITER_UNKNOWN_STREAM) {
561 fprintf(writer_component->err, "[error] Unexpected stream "
562 "state %d\n", *state);
563 goto error;
564 }
565 *state = FS_WRITER_ACTIVE_STREAM;
566
a619fcb7 567 writer_stream = insert_new_stream(writer_component, fs_writer,
f384901f
JD
568 stream_class, stream);
569 if (!writer_stream) {
570 fprintf(writer_component->err, "[error] %s in %s:%d\n",
571 __func__, __FILE__, __LINE__);
572 goto error;
573 }
f384901f
JD
574
575 goto end;
576
577error:
578 ret = BT_COMPONENT_STATUS_ERROR;
579end:
f384901f
JD
580 bt_put(stream_class);
581 return ret;
582}
583
f3168545
JD
584BT_HIDDEN
585enum bt_component_status writer_stream_end(
586 struct writer_component *writer_component,
587 struct bt_ctf_stream *stream)
588{
589 struct bt_ctf_stream_class *stream_class = NULL;
590 struct fs_writer *fs_writer;
591 struct bt_ctf_trace *trace = NULL;
592 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
cdcf612f 593 enum fs_writer_stream_state *state;
f3168545 594
f3168545
JD
595 stream_class = bt_ctf_stream_get_class(stream);
596 if (!stream_class) {
597 fprintf(writer_component->err, "[error] %s in %s:%d\n",
598 __func__, __FILE__, __LINE__);
599 goto error;
600 }
601
602 fs_writer = get_fs_writer(writer_component, stream_class);
603 if (!fs_writer) {
604 fprintf(writer_component->err, "[error] %s in %s:%d\n",
605 __func__, __FILE__, __LINE__);
606 goto error;
607 }
cdcf612f
JD
608
609 state = g_hash_table_lookup(fs_writer->stream_states, stream);
610 if (*state != FS_WRITER_ACTIVE_STREAM) {
611 fprintf(writer_component->err, "[error] Unexpected stream "
612 "state %d\n", *state);
613 goto error;
614 }
615 *state = FS_WRITER_COMPLETED_STREAM;
616
a619fcb7 617 g_hash_table_remove(fs_writer->stream_map, stream);
f3168545 618
cdcf612f
JD
619 if (fs_writer->trace_static) {
620 int trace_completed = 1;
621
622 g_hash_table_foreach(fs_writer->stream_states,
623 check_completed_trace, &trace_completed);
624 if (trace_completed) {
625 writer_close(writer_component, fs_writer);
626 g_hash_table_remove(writer_component->trace_map,
627 fs_writer->trace);
628 }
f3168545
JD
629 }
630
631 goto end;
632
633error:
634 ret = BT_COMPONENT_STATUS_ERROR;
635end:
636 BT_PUT(trace);
637 BT_PUT(stream_class);
638 return ret;
639}
640
bc506aa5
JD
641BT_HIDDEN
642enum bt_component_status writer_new_packet(
643 struct writer_component *writer_component,
644 struct bt_ctf_packet *packet)
645{
9ae49d3d
JD
646 struct bt_ctf_stream *stream = NULL, *writer_stream = NULL;
647 struct bt_ctf_field *writer_packet_context = NULL;
bc506aa5 648 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
b2f1f465 649 int int_ret;
bc506aa5
JD
650
651 stream = bt_ctf_packet_get_stream(packet);
652 if (!stream) {
bc506aa5
JD
653 fprintf(writer_component->err, "[error] %s in %s:%d\n",
654 __func__, __FILE__, __LINE__);
9ae49d3d 655 goto error;
bc506aa5
JD
656 }
657
bc506aa5
JD
658 writer_stream = get_writer_stream(writer_component, packet, stream);
659 if (!writer_stream) {
bc506aa5
JD
660 fprintf(writer_component->err, "[error] %s in %s:%d\n",
661 __func__, __FILE__, __LINE__);
9ae49d3d 662 goto error;
bc506aa5 663 }
9ae49d3d 664 BT_PUT(stream);
bc506aa5 665
b2f1f465 666 writer_packet_context = ctf_copy_packet_context(writer_component->err,
79697a58 667 packet, writer_stream);
b2f1f465 668 if (!writer_packet_context) {
91b73004
JD
669 fprintf(writer_component->err, "[error] %s in %s:%d\n",
670 __func__, __FILE__, __LINE__);
9ae49d3d 671 goto error;
bc506aa5
JD
672 }
673
b2f1f465
JD
674 int_ret = bt_ctf_stream_set_packet_context(writer_stream,
675 writer_packet_context);
676 if (int_ret < 0) {
b2f1f465
JD
677 fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__,
678 __FILE__, __LINE__);
9ae49d3d 679 goto error;
b2f1f465 680 }
9ae49d3d
JD
681 BT_PUT(writer_stream);
682 BT_PUT(writer_packet_context);
b2f1f465 683
9ae49d3d 684 goto end;
bc506aa5 685
9ae49d3d
JD
686error:
687 ret = BT_COMPONENT_STATUS_ERROR;
688end:
689 bt_put(writer_stream);
b2f1f465 690 bt_put(writer_packet_context);
91b73004 691 bt_put(stream);
bc506aa5
JD
692 return ret;
693}
694
695BT_HIDDEN
696enum bt_component_status writer_close_packet(
697 struct writer_component *writer_component,
698 struct bt_ctf_packet *packet)
699{
9ae49d3d 700 struct bt_ctf_stream *stream = NULL, *writer_stream = NULL;
bc506aa5
JD
701 enum bt_component_status ret;
702
703 stream = bt_ctf_packet_get_stream(packet);
704 if (!stream) {
bc506aa5
JD
705 fprintf(writer_component->err, "[error] %s in %s:%d\n",
706 __func__, __FILE__, __LINE__);
9ae49d3d 707 goto error;
bc506aa5
JD
708 }
709
710 writer_stream = lookup_stream(writer_component, stream);
711 if (!writer_stream) {
bc506aa5
JD
712 fprintf(writer_component->err, "[error] %s in %s:%d\n",
713 __func__, __FILE__, __LINE__);
9ae49d3d 714 goto error;
bc506aa5 715 }
9ae49d3d 716 BT_PUT(stream);
bc506aa5 717
9ae49d3d 718 bt_get(writer_stream);
bc506aa5 719
bc506aa5
JD
720 ret = bt_ctf_stream_flush(writer_stream);
721 if (ret < 0) {
722 fprintf(writer_component->err,
723 "[error] Failed to flush packet\n");
9ae49d3d 724 goto error;
bc506aa5 725 }
9ae49d3d 726 BT_PUT(writer_stream);
bc506aa5
JD
727
728 ret = BT_COMPONENT_STATUS_OK;
9ae49d3d 729 goto end;
bc506aa5 730
9ae49d3d
JD
731error:
732 ret = BT_COMPONENT_STATUS_ERROR;
733end:
bc506aa5 734 bt_put(writer_stream);
bc506aa5 735 bt_put(stream);
bc506aa5
JD
736 return ret;
737}
738
bc506aa5
JD
739BT_HIDDEN
740enum bt_component_status writer_output_event(
741 struct writer_component *writer_component,
742 struct bt_ctf_event *event)
743{
744 enum bt_component_status ret;
9ae49d3d
JD
745 struct bt_ctf_event_class *event_class = NULL, *writer_event_class = NULL;
746 struct bt_ctf_stream *stream = NULL, *writer_stream = NULL;
747 struct bt_ctf_stream_class *stream_class = NULL, *writer_stream_class = NULL;
748 struct bt_ctf_event *writer_event = NULL;
bc506aa5
JD
749 const char *event_name;
750 int int_ret;
751
752 event_class = bt_ctf_event_get_class(event);
753 if (!event_class) {
bc506aa5
JD
754 fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__,
755 __FILE__, __LINE__);
9ae49d3d 756 goto error;
bc506aa5
JD
757 }
758
759 event_name = bt_ctf_event_class_get_name(event_class);
760 if (!event_name) {
bc506aa5
JD
761 fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__,
762 __FILE__, __LINE__);
9ae49d3d 763 goto error;
bc506aa5 764 }
bc506aa5
JD
765
766 stream = bt_ctf_event_get_stream(event);
767 if (!stream) {
bc506aa5
JD
768 fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__,
769 __FILE__, __LINE__);
9ae49d3d 770 goto error;
bc506aa5
JD
771 }
772
773 writer_stream = lookup_stream(writer_component, stream);
774 if (!writer_stream || !bt_get(writer_stream)) {
bc506aa5
JD
775 fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__,
776 __FILE__, __LINE__);
9ae49d3d 777 goto error;
bc506aa5
JD
778 }
779
780 stream_class = bt_ctf_event_class_get_stream_class(event_class);
781 if (!stream_class) {
bc506aa5
JD
782 fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__,
783 __FILE__, __LINE__);
9ae49d3d 784 goto error;
bc506aa5
JD
785 }
786
a619fcb7 787 writer_stream_class = lookup_stream_class(writer_component, stream_class);
bc506aa5 788 if (!writer_stream_class || !bt_get(writer_stream_class)) {
bc506aa5
JD
789 fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__,
790 __FILE__, __LINE__);
9ae49d3d 791 goto error;
bc506aa5
JD
792 }
793
794 writer_event_class = get_event_class(writer_component,
795 writer_stream_class, event_class);
796 if (!writer_event_class) {
af34e875
JD
797 writer_event_class = ctf_copy_event_class(writer_component->err,
798 event_class);
799 if (!writer_event_class) {
af34e875
JD
800 fprintf(writer_component->err, "[error] %s in %s:%d\n",
801 __func__, __FILE__, __LINE__);
9ae49d3d 802 goto error;
af34e875
JD
803 }
804 int_ret = bt_ctf_stream_class_add_event_class(
805 writer_stream_class, writer_event_class);
806 if (int_ret) {
af34e875
JD
807 fprintf(writer_component->err, "[error] %s in %s:%d\n",
808 __func__, __FILE__, __LINE__);
9ae49d3d 809 goto error;
af34e875 810 }
bc506aa5
JD
811 }
812
b2f1f465
JD
813 writer_event = ctf_copy_event(writer_component->err, event,
814 writer_event_class, true);
bc506aa5 815 if (!writer_event) {
bc506aa5
JD
816 fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__,
817 __FILE__, __LINE__);
818 fprintf(writer_component->err, "[error] Failed to copy event %s\n",
819 bt_ctf_event_class_get_name(writer_event_class));
9ae49d3d 820 goto error;
bc506aa5
JD
821 }
822
823 int_ret = bt_ctf_stream_append_event(writer_stream, writer_event);
824 if (int_ret < 0) {
bc506aa5
JD
825 fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__,
826 __FILE__, __LINE__);
827 fprintf(writer_component->err, "[error] Failed to append event %s\n",
828 bt_ctf_event_class_get_name(writer_event_class));
9ae49d3d 829 goto error;
bc506aa5
JD
830 }
831
832 ret = BT_COMPONENT_STATUS_OK;
9ae49d3d 833 goto end;
bc506aa5 834
9ae49d3d
JD
835error:
836 ret = BT_COMPONENT_STATUS_ERROR;
837end:
bc506aa5 838 bt_put(writer_event);
bc506aa5 839 bt_put(writer_event_class);
bc506aa5 840 bt_put(writer_stream_class);
bc506aa5 841 bt_put(stream_class);
bc506aa5 842 bt_put(writer_stream);
bc506aa5 843 bt_put(stream);
bc506aa5 844 bt_put(event_class);
bc506aa5
JD
845 return ret;
846}
This page took 0.067233 seconds and 4 git commands to generate.