support adding streams on non-static traces
[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 void destroy_stream_state_key(gpointer key)
62 {
63 g_free((enum fs_writer_stream_state *) key);
64 }
65
66 static
67 void trace_is_static_listener(struct bt_ctf_trace *trace, void *data)
68 {
69 *((int *) data) = 1;
70 }
71
72 static
73 struct bt_ctf_stream_class *insert_new_stream_class(
74 struct writer_component *writer_component,
75 struct fs_writer *fs_writer,
76 struct bt_ctf_stream_class *stream_class)
77 {
78 struct bt_ctf_stream_class *writer_stream_class = NULL;
79 struct bt_ctf_trace *trace = NULL, *writer_trace = NULL;
80 struct bt_ctf_writer *ctf_writer = fs_writer->writer;
81 enum bt_component_status ret;
82
83 trace = bt_ctf_stream_class_get_trace(stream_class);
84 if (!trace) {
85 fprintf(writer_component->err,
86 "[error] %s in %s:%d\n", __func__, __FILE__,
87 __LINE__);
88 goto error;
89 }
90
91 writer_trace = bt_ctf_writer_get_trace(ctf_writer);
92 if (!writer_trace) {
93 fprintf(writer_component->err,
94 "[error] %s in %s:%d\n", __func__, __FILE__,
95 __LINE__);
96 goto error;
97 }
98
99 ret = ctf_copy_clock_classes(writer_component->err, writer_trace,
100 writer_stream_class, trace);
101 if (ret != BT_COMPONENT_STATUS_OK) {
102 fprintf(writer_component->err,
103 "[error] %s in %s:%d\n", __func__, __FILE__,
104 __LINE__);
105 goto error;
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__);
114 goto error;
115 }
116
117 g_hash_table_insert(fs_writer->stream_class_map,
118 (gpointer) stream_class, writer_stream_class);
119
120 goto end;
121
122 error:
123 BT_PUT(writer_stream_class);
124 end:
125 bt_put(writer_trace);
126 bt_put(trace);
127 return writer_stream_class;
128 }
129
130 static
131 enum 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
150 static
151 struct fs_writer *insert_new_writer(
152 struct writer_component *writer_component,
153 struct bt_ctf_trace *trace)
154 {
155 struct bt_ctf_writer *ctf_writer = NULL;
156 struct bt_ctf_trace *writer_trace = NULL;
157 char trace_name[PATH_MAX];
158 enum bt_component_status ret;
159 struct bt_ctf_stream *stream = NULL;
160 struct fs_writer *fs_writer = NULL;
161 int nr_stream, i;
162
163 /* FIXME: replace with trace name when it will work. */
164 snprintf(trace_name, PATH_MAX, "%s/%s_%03d",
165 writer_component->base_path->str,
166 writer_component->trace_name_base->str,
167 writer_component->trace_id++);
168 printf_verbose("CTF-Writer creating trace in %s\n", trace_name);
169
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__);
174 goto error;
175 }
176
177 writer_trace = bt_ctf_writer_get_trace(ctf_writer);
178 if (!writer_trace) {
179 fprintf(writer_component->err,
180 "[error] %s in %s:%d\n", __func__, __FILE__,
181 __LINE__);
182 goto error;
183 }
184
185 ret = ctf_copy_trace(writer_component->err, trace, writer_trace);
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);
191 goto error;
192 }
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;
202 fs_writer->trace = trace;
203 fs_writer->writer_trace = writer_trace;
204 BT_PUT(writer_trace);
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);
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++) {
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 }
222 insert_new_stream_state(writer_component, fs_writer, stream);
223 BT_PUT(stream);
224 }
225
226 /* Check if the trace is already static or register a listener. */
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__);
237 goto error;
238 }
239 fs_writer->static_listener_id = ret;
240 }
241
242 g_hash_table_insert(writer_component->trace_map, (gpointer) trace,
243 fs_writer);
244
245 goto end;
246
247 error:
248 g_free(fs_writer);
249 fs_writer = NULL;
250 bt_put(writer_trace);
251 bt_put(stream);
252 BT_PUT(ctf_writer);
253 end:
254 return fs_writer;
255 }
256
257 static
258 struct fs_writer *get_fs_writer(struct writer_component *writer_component,
259 struct bt_ctf_stream_class *stream_class)
260 {
261 struct bt_ctf_trace *trace = NULL;
262 struct fs_writer *fs_writer;
263
264 trace = bt_ctf_stream_class_get_trace(stream_class);
265 if (!trace) {
266 fprintf(writer_component->err, "[error] %s in %s:%d\n",
267 __func__, __FILE__, __LINE__);
268 goto error;
269 }
270
271 fs_writer = g_hash_table_lookup(writer_component->trace_map,
272 (gpointer) trace);
273 if (!fs_writer) {
274 fs_writer = insert_new_writer(writer_component, trace);
275 }
276 BT_PUT(trace);
277 goto end;
278
279 error:
280 fs_writer = NULL;
281 end:
282 return fs_writer;
283 }
284
285 static
286 struct 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
303 error:
304 fs_writer = NULL;
305
306 end:
307 bt_put(stream_class);
308 return fs_writer;
309 }
310
311 static
312 struct 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
323 static
324 struct 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
334 static
335 struct 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
371 error:
372 BT_PUT(writer_stream);
373 end:
374 bt_put(ctf_writer);
375 bt_put(writer_stream_class);
376 return writer_stream;
377 }
378
379 static
380 struct 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
388 static
389 struct bt_ctf_stream *get_writer_stream(
390 struct writer_component *writer_component,
391 struct bt_ctf_packet *packet, struct bt_ctf_stream *stream)
392 {
393 struct bt_ctf_stream *writer_stream = NULL;
394
395 writer_stream = lookup_stream(writer_component, stream);
396 if (!writer_stream) {
397 fprintf(writer_component->err, "[error] %s in %s:%d\n",
398 __func__, __FILE__, __LINE__);
399 goto error;
400 }
401 bt_get(writer_stream);
402
403 goto end;
404
405 error:
406 BT_PUT(writer_stream);
407 end:
408 return writer_stream;
409 }
410
411 BT_HIDDEN
412 void writer_close(struct writer_component *writer_component,
413 struct fs_writer *fs_writer)
414 {
415 if (fs_writer->static_listener_id > 0) {
416 bt_ctf_trace_remove_is_static_listener(fs_writer->trace,
417 fs_writer->static_listener_id);
418 }
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);
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);
434 }
435
436 BT_HIDDEN
437 enum 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;
443 struct bt_ctf_stream *writer_stream = NULL;
444 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
445 enum fs_writer_stream_state *state;
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 }
460
461 /* Set the stream as active */
462 state = g_hash_table_lookup(fs_writer->stream_states, stream);
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 }
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
479 writer_stream = insert_new_stream(writer_component, fs_writer,
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
490 error:
491 ret = BT_COMPONENT_STATUS_ERROR;
492 end:
493 bt_put(stream_class);
494 return ret;
495 }
496
497 void 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
507 BT_HIDDEN
508 enum 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;
516 enum fs_writer_stream_state *state;
517
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 }
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
540 g_hash_table_remove(fs_writer->stream_map, stream);
541
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 }
552 }
553
554 goto end;
555
556 error:
557 ret = BT_COMPONENT_STATUS_ERROR;
558 end:
559 BT_PUT(trace);
560 BT_PUT(stream_class);
561 return ret;
562 }
563
564 BT_HIDDEN
565 enum bt_component_status writer_new_packet(
566 struct writer_component *writer_component,
567 struct bt_ctf_packet *packet)
568 {
569 struct bt_ctf_stream *stream = NULL, *writer_stream = NULL;
570 struct bt_ctf_field *writer_packet_context = NULL;
571 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
572 int int_ret;
573
574 stream = bt_ctf_packet_get_stream(packet);
575 if (!stream) {
576 fprintf(writer_component->err, "[error] %s in %s:%d\n",
577 __func__, __FILE__, __LINE__);
578 goto error;
579 }
580
581 writer_stream = get_writer_stream(writer_component, packet, stream);
582 if (!writer_stream) {
583 fprintf(writer_component->err, "[error] %s in %s:%d\n",
584 __func__, __FILE__, __LINE__);
585 goto error;
586 }
587 BT_PUT(stream);
588
589 writer_packet_context = ctf_copy_packet_context(writer_component->err,
590 packet, writer_stream, 1);
591 if (!writer_packet_context) {
592 fprintf(writer_component->err, "[error] %s in %s:%d\n",
593 __func__, __FILE__, __LINE__);
594 goto error;
595 }
596
597 int_ret = bt_ctf_stream_set_packet_context(writer_stream,
598 writer_packet_context);
599 if (int_ret < 0) {
600 fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__,
601 __FILE__, __LINE__);
602 goto error;
603 }
604 BT_PUT(writer_stream);
605 BT_PUT(writer_packet_context);
606
607 goto end;
608
609 error:
610 ret = BT_COMPONENT_STATUS_ERROR;
611 end:
612 bt_put(writer_stream);
613 bt_put(writer_packet_context);
614 bt_put(stream);
615 return ret;
616 }
617
618 BT_HIDDEN
619 enum bt_component_status writer_close_packet(
620 struct writer_component *writer_component,
621 struct bt_ctf_packet *packet)
622 {
623 struct bt_ctf_stream *stream = NULL, *writer_stream = NULL;
624 enum bt_component_status ret;
625
626 stream = bt_ctf_packet_get_stream(packet);
627 if (!stream) {
628 fprintf(writer_component->err, "[error] %s in %s:%d\n",
629 __func__, __FILE__, __LINE__);
630 goto error;
631 }
632
633 writer_stream = lookup_stream(writer_component, stream);
634 if (!writer_stream) {
635 fprintf(writer_component->err, "[error] %s in %s:%d\n",
636 __func__, __FILE__, __LINE__);
637 goto error;
638 }
639 BT_PUT(stream);
640
641 bt_get(writer_stream);
642
643 ret = bt_ctf_stream_flush(writer_stream);
644 if (ret < 0) {
645 fprintf(writer_component->err,
646 "[error] Failed to flush packet\n");
647 goto error;
648 }
649 BT_PUT(writer_stream);
650
651 ret = BT_COMPONENT_STATUS_OK;
652 goto end;
653
654 error:
655 ret = BT_COMPONENT_STATUS_ERROR;
656 end:
657 bt_put(writer_stream);
658 bt_put(stream);
659 return ret;
660 }
661
662 BT_HIDDEN
663 enum 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;
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;
672 const char *event_name;
673 int int_ret;
674
675 event_class = bt_ctf_event_get_class(event);
676 if (!event_class) {
677 fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__,
678 __FILE__, __LINE__);
679 goto error;
680 }
681
682 event_name = bt_ctf_event_class_get_name(event_class);
683 if (!event_name) {
684 fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__,
685 __FILE__, __LINE__);
686 goto error;
687 }
688
689 stream = bt_ctf_event_get_stream(event);
690 if (!stream) {
691 fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__,
692 __FILE__, __LINE__);
693 goto error;
694 }
695
696 writer_stream = lookup_stream(writer_component, stream);
697 if (!writer_stream || !bt_get(writer_stream)) {
698 fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__,
699 __FILE__, __LINE__);
700 goto error;
701 }
702
703 stream_class = bt_ctf_event_class_get_stream_class(event_class);
704 if (!stream_class) {
705 fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__,
706 __FILE__, __LINE__);
707 goto error;
708 }
709
710 writer_stream_class = lookup_stream_class(writer_component, stream_class);
711 if (!writer_stream_class || !bt_get(writer_stream_class)) {
712 fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__,
713 __FILE__, __LINE__);
714 goto error;
715 }
716
717 writer_event_class = get_event_class(writer_component,
718 writer_stream_class, event_class);
719 if (!writer_event_class) {
720 writer_event_class = ctf_copy_event_class(writer_component->err,
721 event_class);
722 if (!writer_event_class) {
723 fprintf(writer_component->err, "[error] %s in %s:%d\n",
724 __func__, __FILE__, __LINE__);
725 goto error;
726 }
727 int_ret = bt_ctf_stream_class_add_event_class(
728 writer_stream_class, writer_event_class);
729 if (int_ret) {
730 fprintf(writer_component->err, "[error] %s in %s:%d\n",
731 __func__, __FILE__, __LINE__);
732 goto error;
733 }
734 }
735
736 writer_event = ctf_copy_event(writer_component->err, event,
737 writer_event_class, true);
738 if (!writer_event) {
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));
743 goto error;
744 }
745
746 int_ret = bt_ctf_stream_append_event(writer_stream, writer_event);
747 if (int_ret < 0) {
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));
752 goto error;
753 }
754
755 ret = BT_COMPONENT_STATUS_OK;
756 goto end;
757
758 error:
759 ret = BT_COMPONENT_STATUS_ERROR;
760 end:
761 bt_put(writer_event);
762 bt_put(writer_event_class);
763 bt_put(writer_stream_class);
764 bt_put(stream_class);
765 bt_put(writer_stream);
766 bt_put(stream);
767 bt_put(event_class);
768 return ret;
769 }
This page took 0.048102 seconds and 4 git commands to generate.