fs-sink: useless active_stream member
[babeltrace.git] / plugins / ctf / fs-sink / write.c
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>
34 #include <babeltrace/ctf-ir/clock-class.h>
35 #include <babeltrace/ctf-ir/fields.h>
36 #include <babeltrace/ctf-writer/stream-class.h>
37 #include <babeltrace/ctf-writer/stream.h>
38 #include <assert.h>
39
40 #include <ctfcopytrace.h>
41
42 #include "writer.h"
43
44 static
45 void unref_stream_class(struct bt_ctf_stream_class *writer_stream_class)
46 {
47 bt_put(writer_stream_class);
48 }
49
50 static
51 void unref_stream(struct bt_ctf_stream_class *writer_stream)
52 {
53 bt_put(writer_stream);
54 }
55
56 gboolean empty_ht(gpointer key, gpointer value, gpointer user_data)
57 {
58 return TRUE;
59 }
60
61 gboolean 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
70 void destroy_stream_state_key(gpointer key)
71 {
72 g_free((enum fs_writer_stream_state *) key);
73 }
74
75 void 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
85 static
86 void trace_is_static_listener(struct bt_ctf_trace *trace, void *data)
87 {
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 }
100 }
101
102 static
103 struct bt_ctf_stream_class *insert_new_stream_class(
104 struct writer_component *writer_component,
105 struct fs_writer *fs_writer,
106 struct bt_ctf_stream_class *stream_class)
107 {
108 struct bt_ctf_stream_class *writer_stream_class = NULL;
109 struct bt_ctf_trace *trace = NULL, *writer_trace = NULL;
110 struct bt_ctf_writer *ctf_writer = fs_writer->writer;
111 enum bt_component_status ret;
112
113 trace = bt_ctf_stream_class_get_trace(stream_class);
114 if (!trace) {
115 fprintf(writer_component->err,
116 "[error] %s in %s:%d\n", __func__, __FILE__,
117 __LINE__);
118 goto error;
119 }
120
121 writer_trace = bt_ctf_writer_get_trace(ctf_writer);
122 if (!writer_trace) {
123 fprintf(writer_component->err,
124 "[error] %s in %s:%d\n", __func__, __FILE__,
125 __LINE__);
126 goto error;
127 }
128
129 ret = ctf_copy_clock_classes(writer_component->err, writer_trace,
130 writer_stream_class, trace);
131 if (ret != BT_COMPONENT_STATUS_OK) {
132 fprintf(writer_component->err,
133 "[error] %s in %s:%d\n", __func__, __FILE__,
134 __LINE__);
135 goto error;
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__);
144 goto error;
145 }
146
147 g_hash_table_insert(fs_writer->stream_class_map,
148 (gpointer) stream_class, writer_stream_class);
149
150 goto end;
151
152 error:
153 BT_PUT(writer_stream_class);
154 end:
155 bt_put(writer_trace);
156 bt_put(trace);
157 return writer_stream_class;
158 }
159
160 static
161 enum 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
180 static
181 int 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
229 error:
230 ret = -1;
231 end:
232 return ret;
233 }
234
235 static
236 struct fs_writer *insert_new_writer(
237 struct writer_component *writer_component,
238 struct bt_ctf_trace *trace)
239 {
240 struct bt_ctf_writer *ctf_writer = NULL;
241 struct bt_ctf_trace *writer_trace = NULL;
242 char trace_path[PATH_MAX];
243 enum bt_component_status ret;
244 struct bt_ctf_stream *stream = NULL;
245 struct fs_writer *fs_writer = NULL;
246 int nr_stream, i;
247
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);
256
257 ctf_writer = bt_ctf_writer_create(trace_path);
258 if (!ctf_writer) {
259 fprintf(writer_component->err, "[error] %s in %s:%d\n",
260 __func__, __FILE__, __LINE__);
261 goto error;
262 }
263
264 writer_trace = bt_ctf_writer_get_trace(ctf_writer);
265 if (!writer_trace) {
266 fprintf(writer_component->err,
267 "[error] %s in %s:%d\n", __func__, __FILE__,
268 __LINE__);
269 goto error;
270 }
271
272 ret = ctf_copy_trace(writer_component->err, trace, writer_trace);
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);
278 goto error;
279 }
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;
289 fs_writer->trace = trace;
290 fs_writer->writer_trace = writer_trace;
291 fs_writer->writer_component = writer_component;
292 BT_PUT(writer_trace);
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);
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++) {
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 }
310 insert_new_stream_state(writer_component, fs_writer, stream);
311 BT_PUT(stream);
312 }
313
314 /* Check if the trace is already static or register a listener. */
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,
320 trace_is_static_listener, fs_writer);
321 if (ret < 0) {
322 fprintf(writer_component->err,
323 "[error] %s in %s:%d\n", __func__, __FILE__,
324 __LINE__);
325 goto error;
326 }
327 fs_writer->static_listener_id = ret;
328 }
329
330 g_hash_table_insert(writer_component->trace_map, (gpointer) trace,
331 fs_writer);
332
333 goto end;
334
335 error:
336 g_free(fs_writer);
337 fs_writer = NULL;
338 bt_put(writer_trace);
339 bt_put(stream);
340 BT_PUT(ctf_writer);
341 end:
342 return fs_writer;
343 }
344
345 static
346 struct fs_writer *get_fs_writer(struct writer_component *writer_component,
347 struct bt_ctf_stream_class *stream_class)
348 {
349 struct bt_ctf_trace *trace = NULL;
350 struct fs_writer *fs_writer;
351
352 trace = bt_ctf_stream_class_get_trace(stream_class);
353 if (!trace) {
354 fprintf(writer_component->err, "[error] %s in %s:%d\n",
355 __func__, __FILE__, __LINE__);
356 goto error;
357 }
358
359 fs_writer = g_hash_table_lookup(writer_component->trace_map,
360 (gpointer) trace);
361 if (!fs_writer) {
362 fs_writer = insert_new_writer(writer_component, trace);
363 }
364 BT_PUT(trace);
365 goto end;
366
367 error:
368 fs_writer = NULL;
369 end:
370 return fs_writer;
371 }
372
373 static
374 struct 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
391 error:
392 fs_writer = NULL;
393
394 end:
395 bt_put(stream_class);
396 return fs_writer;
397 }
398
399 static
400 struct 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
411 static
412 struct 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
422 static
423 struct 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
459 error:
460 BT_PUT(writer_stream);
461 end:
462 bt_put(ctf_writer);
463 bt_put(writer_stream_class);
464 return writer_stream;
465 }
466
467 static
468 struct 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
476 static
477 struct bt_ctf_stream *get_writer_stream(
478 struct writer_component *writer_component,
479 struct bt_ctf_packet *packet, struct bt_ctf_stream *stream)
480 {
481 struct bt_ctf_stream *writer_stream = NULL;
482
483 writer_stream = lookup_stream(writer_component, stream);
484 if (!writer_stream) {
485 fprintf(writer_component->err, "[error] %s in %s:%d\n",
486 __func__, __FILE__, __LINE__);
487 goto error;
488 }
489 bt_get(writer_stream);
490
491 goto end;
492
493 error:
494 BT_PUT(writer_stream);
495 end:
496 return writer_stream;
497 }
498
499 BT_HIDDEN
500 void writer_close(struct writer_component *writer_component,
501 struct fs_writer *fs_writer)
502 {
503 if (fs_writer->static_listener_id > 0) {
504 bt_ctf_trace_remove_is_static_listener(fs_writer->trace,
505 fs_writer->static_listener_id);
506 }
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,
515 empty_streams_ht, NULL);
516 g_hash_table_destroy(fs_writer->stream_map);
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);
522 }
523
524 BT_HIDDEN
525 enum 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;
531 struct bt_ctf_stream *writer_stream = NULL;
532 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
533 enum fs_writer_stream_state *state;
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 }
548
549 /* Set the stream as active */
550 state = g_hash_table_lookup(fs_writer->stream_states, stream);
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 }
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
567 writer_stream = insert_new_stream(writer_component, fs_writer,
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 }
574
575 goto end;
576
577 error:
578 ret = BT_COMPONENT_STATUS_ERROR;
579 end:
580 bt_put(stream_class);
581 return ret;
582 }
583
584 BT_HIDDEN
585 enum 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;
593 enum fs_writer_stream_state *state;
594
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 }
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
617 g_hash_table_remove(fs_writer->stream_map, stream);
618
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 }
629 }
630
631 goto end;
632
633 error:
634 ret = BT_COMPONENT_STATUS_ERROR;
635 end:
636 BT_PUT(trace);
637 BT_PUT(stream_class);
638 return ret;
639 }
640
641 BT_HIDDEN
642 enum bt_component_status writer_new_packet(
643 struct writer_component *writer_component,
644 struct bt_ctf_packet *packet)
645 {
646 struct bt_ctf_stream *stream = NULL, *writer_stream = NULL;
647 struct bt_ctf_field *writer_packet_context = NULL;
648 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
649 int int_ret;
650
651 stream = bt_ctf_packet_get_stream(packet);
652 if (!stream) {
653 fprintf(writer_component->err, "[error] %s in %s:%d\n",
654 __func__, __FILE__, __LINE__);
655 goto error;
656 }
657
658 writer_stream = get_writer_stream(writer_component, packet, stream);
659 if (!writer_stream) {
660 fprintf(writer_component->err, "[error] %s in %s:%d\n",
661 __func__, __FILE__, __LINE__);
662 goto error;
663 }
664 BT_PUT(stream);
665
666 writer_packet_context = ctf_copy_packet_context(writer_component->err,
667 packet, writer_stream);
668 if (!writer_packet_context) {
669 fprintf(writer_component->err, "[error] %s in %s:%d\n",
670 __func__, __FILE__, __LINE__);
671 goto error;
672 }
673
674 int_ret = bt_ctf_stream_set_packet_context(writer_stream,
675 writer_packet_context);
676 if (int_ret < 0) {
677 fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__,
678 __FILE__, __LINE__);
679 goto error;
680 }
681 BT_PUT(writer_stream);
682 BT_PUT(writer_packet_context);
683
684 goto end;
685
686 error:
687 ret = BT_COMPONENT_STATUS_ERROR;
688 end:
689 bt_put(writer_stream);
690 bt_put(writer_packet_context);
691 bt_put(stream);
692 return ret;
693 }
694
695 BT_HIDDEN
696 enum bt_component_status writer_close_packet(
697 struct writer_component *writer_component,
698 struct bt_ctf_packet *packet)
699 {
700 struct bt_ctf_stream *stream = NULL, *writer_stream = NULL;
701 enum bt_component_status ret;
702
703 stream = bt_ctf_packet_get_stream(packet);
704 if (!stream) {
705 fprintf(writer_component->err, "[error] %s in %s:%d\n",
706 __func__, __FILE__, __LINE__);
707 goto error;
708 }
709
710 writer_stream = lookup_stream(writer_component, stream);
711 if (!writer_stream) {
712 fprintf(writer_component->err, "[error] %s in %s:%d\n",
713 __func__, __FILE__, __LINE__);
714 goto error;
715 }
716 BT_PUT(stream);
717
718 bt_get(writer_stream);
719
720 ret = bt_ctf_stream_flush(writer_stream);
721 if (ret < 0) {
722 fprintf(writer_component->err,
723 "[error] Failed to flush packet\n");
724 goto error;
725 }
726 BT_PUT(writer_stream);
727
728 ret = BT_COMPONENT_STATUS_OK;
729 goto end;
730
731 error:
732 ret = BT_COMPONENT_STATUS_ERROR;
733 end:
734 bt_put(writer_stream);
735 bt_put(stream);
736 return ret;
737 }
738
739 BT_HIDDEN
740 enum 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;
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;
749 const char *event_name;
750 int int_ret;
751
752 event_class = bt_ctf_event_get_class(event);
753 if (!event_class) {
754 fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__,
755 __FILE__, __LINE__);
756 goto error;
757 }
758
759 event_name = bt_ctf_event_class_get_name(event_class);
760 if (!event_name) {
761 fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__,
762 __FILE__, __LINE__);
763 goto error;
764 }
765
766 stream = bt_ctf_event_get_stream(event);
767 if (!stream) {
768 fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__,
769 __FILE__, __LINE__);
770 goto error;
771 }
772
773 writer_stream = lookup_stream(writer_component, stream);
774 if (!writer_stream || !bt_get(writer_stream)) {
775 fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__,
776 __FILE__, __LINE__);
777 goto error;
778 }
779
780 stream_class = bt_ctf_event_class_get_stream_class(event_class);
781 if (!stream_class) {
782 fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__,
783 __FILE__, __LINE__);
784 goto error;
785 }
786
787 writer_stream_class = lookup_stream_class(writer_component, stream_class);
788 if (!writer_stream_class || !bt_get(writer_stream_class)) {
789 fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__,
790 __FILE__, __LINE__);
791 goto error;
792 }
793
794 writer_event_class = get_event_class(writer_component,
795 writer_stream_class, event_class);
796 if (!writer_event_class) {
797 writer_event_class = ctf_copy_event_class(writer_component->err,
798 event_class);
799 if (!writer_event_class) {
800 fprintf(writer_component->err, "[error] %s in %s:%d\n",
801 __func__, __FILE__, __LINE__);
802 goto error;
803 }
804 int_ret = bt_ctf_stream_class_add_event_class(
805 writer_stream_class, writer_event_class);
806 if (int_ret) {
807 fprintf(writer_component->err, "[error] %s in %s:%d\n",
808 __func__, __FILE__, __LINE__);
809 goto error;
810 }
811 }
812
813 writer_event = ctf_copy_event(writer_component->err, event,
814 writer_event_class, true);
815 if (!writer_event) {
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));
820 goto error;
821 }
822
823 int_ret = bt_ctf_stream_append_event(writer_stream, writer_event);
824 if (int_ret < 0) {
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));
829 goto error;
830 }
831
832 ret = BT_COMPONENT_STATUS_OK;
833 goto end;
834
835 error:
836 ret = BT_COMPONENT_STATUS_ERROR;
837 end:
838 bt_put(writer_event);
839 bt_put(writer_event_class);
840 bt_put(writer_stream_class);
841 bt_put(stream_class);
842 bt_put(writer_stream);
843 bt_put(stream);
844 bt_put(event_class);
845 return ret;
846 }
This page took 0.046213 seconds and 4 git commands to generate.