Commit | Line | Data |
---|---|---|
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 | ||
f3168545 JD |
44 | static |
45 | void trace_is_static_listener(struct bt_ctf_trace *trace, void *data) | |
46 | { | |
47 | *((int *) data) = 1; | |
48 | } | |
49 | ||
bc506aa5 | 50 | static |
91b73004 JD |
51 | struct bt_ctf_stream_class *insert_new_stream_class( |
52 | struct writer_component *writer_component, | |
53 | struct bt_ctf_writer *ctf_writer, | |
54 | struct bt_ctf_stream_class *stream_class) | |
bc506aa5 | 55 | { |
b2f1f465 | 56 | struct bt_ctf_stream_class *writer_stream_class = NULL; |
9ae49d3d | 57 | struct bt_ctf_trace *trace = NULL, *writer_trace = NULL; |
3241bc18 | 58 | enum bt_component_status ret; |
bc506aa5 | 59 | |
3241bc18 JD |
60 | trace = bt_ctf_stream_class_get_trace(stream_class); |
61 | if (!trace) { | |
91b73004 JD |
62 | fprintf(writer_component->err, |
63 | "[error] %s in %s:%d\n", __func__, __FILE__, | |
bc506aa5 | 64 | __LINE__); |
9ae49d3d | 65 | goto error; |
bc506aa5 JD |
66 | } |
67 | ||
91b73004 JD |
68 | writer_trace = bt_ctf_writer_get_trace(ctf_writer); |
69 | if (!writer_trace) { | |
91b73004 JD |
70 | fprintf(writer_component->err, |
71 | "[error] %s in %s:%d\n", __func__, __FILE__, | |
d00b90bf | 72 | __LINE__); |
9ae49d3d | 73 | goto error; |
bc506aa5 JD |
74 | } |
75 | ||
91b73004 JD |
76 | ret = ctf_copy_clock_classes(writer_component->err, writer_trace, |
77 | writer_stream_class, trace); | |
bc506aa5 | 78 | if (ret != BT_COMPONENT_STATUS_OK) { |
91b73004 JD |
79 | fprintf(writer_component->err, |
80 | "[error] %s in %s:%d\n", __func__, __FILE__, | |
bc506aa5 | 81 | __LINE__); |
9ae49d3d | 82 | goto error; |
b2f1f465 JD |
83 | } |
84 | ||
85 | writer_stream_class = ctf_copy_stream_class(writer_component->err, | |
86 | stream_class, writer_trace, true); | |
87 | if (!writer_stream_class) { | |
88 | fprintf(writer_component->err, "[error] Failed to copy stream class\n"); | |
89 | fprintf(writer_component->err, "[error] %s in %s:%d\n", | |
90 | __func__, __FILE__, __LINE__); | |
9ae49d3d | 91 | goto error; |
bc506aa5 | 92 | } |
bc506aa5 | 93 | |
bc506aa5 JD |
94 | g_hash_table_insert(writer_component->stream_class_map, |
95 | (gpointer) stream_class, writer_stream_class); | |
96 | ||
9ae49d3d JD |
97 | goto end; |
98 | ||
99 | error: | |
100 | BT_PUT(writer_stream_class); | |
101 | end: | |
b2f1f465 | 102 | bt_put(writer_trace); |
b2f1f465 | 103 | bt_put(trace); |
bc506aa5 JD |
104 | return writer_stream_class; |
105 | } | |
106 | ||
107 | static | |
108 | struct bt_ctf_stream *insert_new_stream( | |
109 | struct writer_component *writer_component, | |
110 | struct bt_ctf_writer *ctf_writer, | |
111 | struct bt_ctf_stream_class *stream_class, | |
112 | struct bt_ctf_stream *stream) | |
113 | { | |
9ae49d3d JD |
114 | struct bt_ctf_stream *writer_stream = NULL; |
115 | struct bt_ctf_stream_class *writer_stream_class = NULL; | |
bc506aa5 JD |
116 | |
117 | writer_stream_class = g_hash_table_lookup( | |
118 | writer_component->stream_class_map, | |
119 | (gpointer) stream_class); | |
9ae49d3d | 120 | if (!writer_stream_class) { |
bc506aa5 JD |
121 | writer_stream_class = insert_new_stream_class( |
122 | writer_component, ctf_writer, stream_class); | |
123 | if (!writer_stream_class) { | |
bc506aa5 JD |
124 | fprintf(writer_component->err, "[error] %s in %s:%d\n", |
125 | __func__, __FILE__, __LINE__); | |
9ae49d3d | 126 | goto error; |
bc506aa5 JD |
127 | } |
128 | } | |
9ae49d3d | 129 | bt_get(writer_stream_class); |
bc506aa5 JD |
130 | |
131 | writer_stream = bt_ctf_writer_create_stream(ctf_writer, | |
132 | writer_stream_class); | |
133 | if (!writer_stream) { | |
134 | fprintf(writer_component->err, "[error] %s in %s:%d\n", | |
135 | __func__, __FILE__, __LINE__); | |
9ae49d3d | 136 | goto error; |
bc506aa5 JD |
137 | } |
138 | ||
139 | g_hash_table_insert(writer_component->stream_map, (gpointer) stream, | |
140 | writer_stream); | |
141 | ||
9ae49d3d | 142 | goto end; |
bc506aa5 | 143 | |
9ae49d3d JD |
144 | error: |
145 | BT_PUT(writer_stream); | |
bc506aa5 | 146 | end: |
9ae49d3d | 147 | bt_put(writer_stream_class); |
bc506aa5 JD |
148 | return writer_stream; |
149 | } | |
150 | ||
151 | static | |
152 | struct bt_ctf_stream *lookup_stream(struct writer_component *writer_component, | |
153 | struct bt_ctf_stream *stream) | |
154 | { | |
155 | return (struct bt_ctf_stream *) g_hash_table_lookup( | |
156 | writer_component->stream_map, | |
157 | (gpointer) stream); | |
158 | } | |
159 | ||
160 | static | |
161 | struct bt_ctf_event_class *get_event_class(struct writer_component *writer_component, | |
162 | struct bt_ctf_stream_class *writer_stream_class, | |
163 | struct bt_ctf_event_class *event_class) | |
164 | { | |
a9f0d01b PP |
165 | return bt_ctf_stream_class_get_event_class_by_id(writer_stream_class, |
166 | bt_ctf_event_class_get_id(event_class)); | |
bc506aa5 JD |
167 | } |
168 | ||
f3168545 | 169 | struct fs_writer *insert_new_writer( |
bc506aa5 JD |
170 | struct writer_component *writer_component, |
171 | struct bt_ctf_trace *trace) | |
172 | { | |
9ae49d3d JD |
173 | struct bt_ctf_writer *ctf_writer = NULL; |
174 | struct bt_ctf_trace *writer_trace = NULL; | |
bc506aa5 JD |
175 | char trace_name[PATH_MAX]; |
176 | enum bt_component_status ret; | |
f3168545 | 177 | struct fs_writer *fs_writer; |
bc506aa5 | 178 | |
9ae49d3d | 179 | /* FIXME: replace with trace name when it will work. */ |
bc506aa5 | 180 | snprintf(trace_name, PATH_MAX, "%s/%s_%03d", |
9057f037 JD |
181 | writer_component->base_path->str, |
182 | writer_component->trace_name_base->str, | |
bc506aa5 JD |
183 | writer_component->trace_id++); |
184 | printf_verbose("CTF-Writer creating trace in %s\n", trace_name); | |
9057f037 | 185 | |
bc506aa5 JD |
186 | ctf_writer = bt_ctf_writer_create(trace_name); |
187 | if (!ctf_writer) { | |
188 | fprintf(writer_component->err, "[error] %s in %s:%d\n", | |
189 | __func__, __FILE__, __LINE__); | |
9ae49d3d | 190 | goto error; |
bc506aa5 JD |
191 | } |
192 | ||
91b73004 JD |
193 | writer_trace = bt_ctf_writer_get_trace(ctf_writer); |
194 | if (!writer_trace) { | |
91b73004 JD |
195 | fprintf(writer_component->err, |
196 | "[error] %s in %s:%d\n", __func__, __FILE__, | |
197 | __LINE__); | |
9ae49d3d | 198 | goto error; |
91b73004 JD |
199 | } |
200 | ||
201 | ret = ctf_copy_trace(writer_component->err, trace, writer_trace); | |
bc506aa5 JD |
202 | if (ret != BT_COMPONENT_STATUS_OK) { |
203 | fprintf(writer_component->err, "[error] Failed to copy trace\n"); | |
204 | fprintf(writer_component->err, "[error] %s in %s:%d\n", | |
205 | __func__, __FILE__, __LINE__); | |
206 | BT_PUT(ctf_writer); | |
f3168545 | 207 | goto error; |
bc506aa5 | 208 | } |
f3168545 JD |
209 | |
210 | fs_writer = g_new0(struct fs_writer, 1); | |
211 | if (!fs_writer) { | |
212 | fprintf(writer_component->err, | |
213 | "[error] %s in %s:%d\n", __func__, __FILE__, | |
214 | __LINE__); | |
215 | goto error; | |
216 | } | |
217 | fs_writer->writer = ctf_writer; | |
218 | fs_writer->writer_trace = writer_trace; | |
9ae49d3d | 219 | BT_PUT(writer_trace); |
f3168545 JD |
220 | if (bt_ctf_trace_is_static(trace)) { |
221 | fs_writer->trace_static = 1; | |
222 | fs_writer->static_listener_id = -1; | |
223 | } else { | |
224 | ret = bt_ctf_trace_add_is_static_listener(trace, | |
225 | trace_is_static_listener, &fs_writer->trace_static); | |
226 | if (ret < 0) { | |
227 | fprintf(writer_component->err, | |
228 | "[error] %s in %s:%d\n", __func__, __FILE__, | |
229 | __LINE__); | |
230 | g_free(fs_writer); | |
231 | fs_writer = NULL; | |
232 | goto error; | |
233 | } | |
234 | fs_writer->static_listener_id = ret; | |
235 | } | |
bc506aa5 JD |
236 | |
237 | g_hash_table_insert(writer_component->trace_map, (gpointer) trace, | |
f3168545 | 238 | fs_writer); |
bc506aa5 | 239 | |
9ae49d3d JD |
240 | goto end; |
241 | ||
242 | error: | |
243 | bt_put(writer_trace); | |
244 | BT_PUT(ctf_writer); | |
bc506aa5 | 245 | end: |
f3168545 | 246 | return fs_writer; |
bc506aa5 JD |
247 | } |
248 | ||
249 | static | |
f3168545 | 250 | struct fs_writer *get_fs_writer(struct writer_component *writer_component, |
bc506aa5 JD |
251 | struct bt_ctf_stream_class *stream_class) |
252 | { | |
9ae49d3d | 253 | struct bt_ctf_trace *trace = NULL; |
f3168545 | 254 | struct fs_writer *fs_writer; |
bc506aa5 JD |
255 | |
256 | trace = bt_ctf_stream_class_get_trace(stream_class); | |
257 | if (!trace) { | |
bc506aa5 JD |
258 | fprintf(writer_component->err, "[error] %s in %s:%d\n", |
259 | __func__, __FILE__, __LINE__); | |
9ae49d3d | 260 | goto error; |
bc506aa5 JD |
261 | } |
262 | ||
f3168545 | 263 | fs_writer = g_hash_table_lookup(writer_component->trace_map, |
bc506aa5 | 264 | (gpointer) trace); |
f3168545 JD |
265 | if (!fs_writer) { |
266 | fs_writer = insert_new_writer(writer_component, trace); | |
bc506aa5 | 267 | } |
9ae49d3d JD |
268 | BT_PUT(trace); |
269 | goto end; | |
bc506aa5 | 270 | |
9ae49d3d | 271 | error: |
f3168545 | 272 | fs_writer = NULL; |
bc506aa5 | 273 | end: |
f3168545 | 274 | return fs_writer; |
bc506aa5 JD |
275 | } |
276 | ||
277 | static | |
278 | struct bt_ctf_stream *get_writer_stream( | |
279 | struct writer_component *writer_component, | |
280 | struct bt_ctf_packet *packet, struct bt_ctf_stream *stream) | |
281 | { | |
9ae49d3d | 282 | struct bt_ctf_stream *writer_stream = NULL; |
bc506aa5 | 283 | |
f384901f JD |
284 | writer_stream = lookup_stream(writer_component, stream); |
285 | if (!writer_stream) { | |
bc506aa5 JD |
286 | fprintf(writer_component->err, "[error] %s in %s:%d\n", |
287 | __func__, __FILE__, __LINE__); | |
9ae49d3d | 288 | goto error; |
bc506aa5 | 289 | } |
9ae49d3d JD |
290 | bt_get(writer_stream); |
291 | ||
292 | goto end; | |
bc506aa5 | 293 | |
9ae49d3d JD |
294 | error: |
295 | BT_PUT(writer_stream); | |
296 | end: | |
bc506aa5 JD |
297 | return writer_stream; |
298 | } | |
299 | ||
f3168545 JD |
300 | BT_HIDDEN |
301 | enum bt_component_status writer_close( | |
302 | struct writer_component *writer_component, | |
303 | struct fs_writer *fs_writer, | |
304 | struct bt_ctf_trace *trace) | |
305 | { | |
306 | enum bt_component_status ret = BT_COMPONENT_STATUS_OK; | |
307 | ||
308 | if (fs_writer->static_listener_id > 0) { | |
309 | bt_ctf_trace_remove_is_static_listener(trace, | |
310 | fs_writer->static_listener_id); | |
311 | } | |
312 | g_hash_table_remove(writer_component->trace_map, trace); | |
313 | return ret; | |
314 | } | |
315 | ||
f384901f JD |
316 | BT_HIDDEN |
317 | enum bt_component_status writer_stream_begin( | |
318 | struct writer_component *writer_component, | |
319 | struct bt_ctf_stream *stream) | |
320 | { | |
321 | struct bt_ctf_stream_class *stream_class = NULL; | |
322 | struct fs_writer *fs_writer; | |
323 | struct bt_ctf_writer *ctf_writer = NULL; | |
324 | struct bt_ctf_stream *writer_stream = NULL; | |
325 | enum bt_component_status ret = BT_COMPONENT_STATUS_OK; | |
326 | ||
327 | stream_class = bt_ctf_stream_get_class(stream); | |
328 | if (!stream_class) { | |
329 | fprintf(writer_component->err, "[error] %s in %s:%d\n", | |
330 | __func__, __FILE__, __LINE__); | |
331 | goto error; | |
332 | } | |
333 | ||
334 | fs_writer = get_fs_writer(writer_component, stream_class); | |
335 | if (!fs_writer) { | |
336 | fprintf(writer_component->err, "[error] %s in %s:%d\n", | |
337 | __func__, __FILE__, __LINE__); | |
338 | goto error; | |
339 | } | |
340 | ctf_writer = bt_get(fs_writer->writer); | |
341 | writer_stream = insert_new_stream(writer_component, ctf_writer, | |
342 | stream_class, stream); | |
343 | if (!writer_stream) { | |
344 | fprintf(writer_component->err, "[error] %s in %s:%d\n", | |
345 | __func__, __FILE__, __LINE__); | |
346 | goto error; | |
347 | } | |
348 | fs_writer->active_streams++; | |
349 | ||
350 | goto end; | |
351 | ||
352 | error: | |
353 | ret = BT_COMPONENT_STATUS_ERROR; | |
354 | end: | |
355 | bt_put(ctf_writer); | |
356 | bt_put(stream_class); | |
357 | return ret; | |
358 | } | |
359 | ||
f3168545 JD |
360 | BT_HIDDEN |
361 | enum bt_component_status writer_stream_end( | |
362 | struct writer_component *writer_component, | |
363 | struct bt_ctf_stream *stream) | |
364 | { | |
365 | struct bt_ctf_stream_class *stream_class = NULL; | |
366 | struct fs_writer *fs_writer; | |
367 | struct bt_ctf_trace *trace = NULL; | |
368 | enum bt_component_status ret = BT_COMPONENT_STATUS_OK; | |
369 | ||
370 | g_hash_table_remove(writer_component->stream_map, stream); | |
371 | ||
372 | stream_class = bt_ctf_stream_get_class(stream); | |
373 | if (!stream_class) { | |
374 | fprintf(writer_component->err, "[error] %s in %s:%d\n", | |
375 | __func__, __FILE__, __LINE__); | |
376 | goto error; | |
377 | } | |
378 | ||
379 | fs_writer = get_fs_writer(writer_component, stream_class); | |
380 | if (!fs_writer) { | |
381 | fprintf(writer_component->err, "[error] %s in %s:%d\n", | |
382 | __func__, __FILE__, __LINE__); | |
383 | goto error; | |
384 | } | |
385 | ||
386 | assert(fs_writer->active_streams > 0); | |
387 | fs_writer->active_streams--; | |
388 | if (fs_writer->active_streams == 0 && fs_writer->trace_static) { | |
389 | trace = bt_ctf_stream_class_get_trace(stream_class); | |
390 | if (!trace) { | |
391 | fprintf(writer_component->err, "[error] %s in %s:%d\n", | |
392 | __func__, __FILE__, __LINE__); | |
393 | goto error; | |
394 | } | |
395 | ret = writer_close(writer_component, fs_writer, trace); | |
396 | } | |
397 | ||
398 | goto end; | |
399 | ||
400 | error: | |
401 | ret = BT_COMPONENT_STATUS_ERROR; | |
402 | end: | |
403 | BT_PUT(trace); | |
404 | BT_PUT(stream_class); | |
405 | return ret; | |
406 | } | |
407 | ||
bc506aa5 JD |
408 | BT_HIDDEN |
409 | enum bt_component_status writer_new_packet( | |
410 | struct writer_component *writer_component, | |
411 | struct bt_ctf_packet *packet) | |
412 | { | |
9ae49d3d JD |
413 | struct bt_ctf_stream *stream = NULL, *writer_stream = NULL; |
414 | struct bt_ctf_field *writer_packet_context = NULL; | |
bc506aa5 | 415 | enum bt_component_status ret = BT_COMPONENT_STATUS_OK; |
b2f1f465 | 416 | int int_ret; |
bc506aa5 JD |
417 | |
418 | stream = bt_ctf_packet_get_stream(packet); | |
419 | if (!stream) { | |
bc506aa5 JD |
420 | fprintf(writer_component->err, "[error] %s in %s:%d\n", |
421 | __func__, __FILE__, __LINE__); | |
9ae49d3d | 422 | goto error; |
bc506aa5 JD |
423 | } |
424 | ||
bc506aa5 JD |
425 | writer_stream = get_writer_stream(writer_component, packet, stream); |
426 | if (!writer_stream) { | |
bc506aa5 JD |
427 | fprintf(writer_component->err, "[error] %s in %s:%d\n", |
428 | __func__, __FILE__, __LINE__); | |
9ae49d3d | 429 | goto error; |
bc506aa5 | 430 | } |
9ae49d3d | 431 | BT_PUT(stream); |
bc506aa5 | 432 | |
b2f1f465 | 433 | writer_packet_context = ctf_copy_packet_context(writer_component->err, |
ab80adac | 434 | packet, writer_stream, 1); |
b2f1f465 | 435 | if (!writer_packet_context) { |
91b73004 JD |
436 | fprintf(writer_component->err, "[error] %s in %s:%d\n", |
437 | __func__, __FILE__, __LINE__); | |
9ae49d3d | 438 | goto error; |
bc506aa5 JD |
439 | } |
440 | ||
b2f1f465 JD |
441 | int_ret = bt_ctf_stream_set_packet_context(writer_stream, |
442 | writer_packet_context); | |
443 | if (int_ret < 0) { | |
b2f1f465 JD |
444 | fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__, |
445 | __FILE__, __LINE__); | |
9ae49d3d | 446 | goto error; |
b2f1f465 | 447 | } |
9ae49d3d JD |
448 | BT_PUT(writer_stream); |
449 | BT_PUT(writer_packet_context); | |
b2f1f465 | 450 | |
9ae49d3d | 451 | goto end; |
bc506aa5 | 452 | |
9ae49d3d JD |
453 | error: |
454 | ret = BT_COMPONENT_STATUS_ERROR; | |
455 | end: | |
456 | bt_put(writer_stream); | |
b2f1f465 | 457 | bt_put(writer_packet_context); |
91b73004 | 458 | bt_put(stream); |
bc506aa5 JD |
459 | return ret; |
460 | } | |
461 | ||
462 | BT_HIDDEN | |
463 | enum bt_component_status writer_close_packet( | |
464 | struct writer_component *writer_component, | |
465 | struct bt_ctf_packet *packet) | |
466 | { | |
9ae49d3d | 467 | struct bt_ctf_stream *stream = NULL, *writer_stream = NULL; |
bc506aa5 JD |
468 | enum bt_component_status ret; |
469 | ||
470 | stream = bt_ctf_packet_get_stream(packet); | |
471 | if (!stream) { | |
bc506aa5 JD |
472 | fprintf(writer_component->err, "[error] %s in %s:%d\n", |
473 | __func__, __FILE__, __LINE__); | |
9ae49d3d | 474 | goto error; |
bc506aa5 JD |
475 | } |
476 | ||
477 | writer_stream = lookup_stream(writer_component, stream); | |
478 | if (!writer_stream) { | |
bc506aa5 JD |
479 | fprintf(writer_component->err, "[error] %s in %s:%d\n", |
480 | __func__, __FILE__, __LINE__); | |
9ae49d3d | 481 | goto error; |
bc506aa5 | 482 | } |
9ae49d3d | 483 | BT_PUT(stream); |
bc506aa5 | 484 | |
9ae49d3d | 485 | bt_get(writer_stream); |
bc506aa5 | 486 | |
bc506aa5 JD |
487 | ret = bt_ctf_stream_flush(writer_stream); |
488 | if (ret < 0) { | |
489 | fprintf(writer_component->err, | |
490 | "[error] Failed to flush packet\n"); | |
9ae49d3d | 491 | goto error; |
bc506aa5 | 492 | } |
9ae49d3d | 493 | BT_PUT(writer_stream); |
bc506aa5 JD |
494 | |
495 | ret = BT_COMPONENT_STATUS_OK; | |
9ae49d3d | 496 | goto end; |
bc506aa5 | 497 | |
9ae49d3d JD |
498 | error: |
499 | ret = BT_COMPONENT_STATUS_ERROR; | |
500 | end: | |
bc506aa5 | 501 | bt_put(writer_stream); |
bc506aa5 | 502 | bt_put(stream); |
bc506aa5 JD |
503 | return ret; |
504 | } | |
505 | ||
bc506aa5 JD |
506 | BT_HIDDEN |
507 | enum bt_component_status writer_output_event( | |
508 | struct writer_component *writer_component, | |
509 | struct bt_ctf_event *event) | |
510 | { | |
511 | enum bt_component_status ret; | |
9ae49d3d JD |
512 | struct bt_ctf_event_class *event_class = NULL, *writer_event_class = NULL; |
513 | struct bt_ctf_stream *stream = NULL, *writer_stream = NULL; | |
514 | struct bt_ctf_stream_class *stream_class = NULL, *writer_stream_class = NULL; | |
515 | struct bt_ctf_event *writer_event = NULL; | |
bc506aa5 JD |
516 | const char *event_name; |
517 | int int_ret; | |
518 | ||
519 | event_class = bt_ctf_event_get_class(event); | |
520 | if (!event_class) { | |
bc506aa5 JD |
521 | fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__, |
522 | __FILE__, __LINE__); | |
9ae49d3d | 523 | goto error; |
bc506aa5 JD |
524 | } |
525 | ||
526 | event_name = bt_ctf_event_class_get_name(event_class); | |
527 | if (!event_name) { | |
bc506aa5 JD |
528 | fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__, |
529 | __FILE__, __LINE__); | |
9ae49d3d | 530 | goto error; |
bc506aa5 | 531 | } |
bc506aa5 JD |
532 | |
533 | stream = bt_ctf_event_get_stream(event); | |
534 | if (!stream) { | |
bc506aa5 JD |
535 | fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__, |
536 | __FILE__, __LINE__); | |
9ae49d3d | 537 | goto error; |
bc506aa5 JD |
538 | } |
539 | ||
540 | writer_stream = lookup_stream(writer_component, stream); | |
541 | if (!writer_stream || !bt_get(writer_stream)) { | |
bc506aa5 JD |
542 | fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__, |
543 | __FILE__, __LINE__); | |
9ae49d3d | 544 | goto error; |
bc506aa5 JD |
545 | } |
546 | ||
547 | stream_class = bt_ctf_event_class_get_stream_class(event_class); | |
548 | if (!stream_class) { | |
bc506aa5 JD |
549 | fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__, |
550 | __FILE__, __LINE__); | |
9ae49d3d | 551 | goto error; |
bc506aa5 JD |
552 | } |
553 | ||
554 | writer_stream_class = g_hash_table_lookup( | |
555 | writer_component->stream_class_map, | |
556 | (gpointer) stream_class); | |
557 | if (!writer_stream_class || !bt_get(writer_stream_class)) { | |
bc506aa5 JD |
558 | fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__, |
559 | __FILE__, __LINE__); | |
9ae49d3d | 560 | goto error; |
bc506aa5 JD |
561 | } |
562 | ||
563 | writer_event_class = get_event_class(writer_component, | |
564 | writer_stream_class, event_class); | |
565 | if (!writer_event_class) { | |
af34e875 JD |
566 | writer_event_class = ctf_copy_event_class(writer_component->err, |
567 | event_class); | |
568 | if (!writer_event_class) { | |
af34e875 JD |
569 | fprintf(writer_component->err, "[error] %s in %s:%d\n", |
570 | __func__, __FILE__, __LINE__); | |
9ae49d3d | 571 | goto error; |
af34e875 JD |
572 | } |
573 | int_ret = bt_ctf_stream_class_add_event_class( | |
574 | writer_stream_class, writer_event_class); | |
575 | if (int_ret) { | |
af34e875 JD |
576 | fprintf(writer_component->err, "[error] %s in %s:%d\n", |
577 | __func__, __FILE__, __LINE__); | |
9ae49d3d | 578 | goto error; |
af34e875 | 579 | } |
bc506aa5 JD |
580 | } |
581 | ||
b2f1f465 JD |
582 | writer_event = ctf_copy_event(writer_component->err, event, |
583 | writer_event_class, true); | |
bc506aa5 | 584 | if (!writer_event) { |
bc506aa5 JD |
585 | fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__, |
586 | __FILE__, __LINE__); | |
587 | fprintf(writer_component->err, "[error] Failed to copy event %s\n", | |
588 | bt_ctf_event_class_get_name(writer_event_class)); | |
9ae49d3d | 589 | goto error; |
bc506aa5 JD |
590 | } |
591 | ||
592 | int_ret = bt_ctf_stream_append_event(writer_stream, writer_event); | |
593 | if (int_ret < 0) { | |
bc506aa5 JD |
594 | fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__, |
595 | __FILE__, __LINE__); | |
596 | fprintf(writer_component->err, "[error] Failed to append event %s\n", | |
597 | bt_ctf_event_class_get_name(writer_event_class)); | |
9ae49d3d | 598 | goto error; |
bc506aa5 JD |
599 | } |
600 | ||
601 | ret = BT_COMPONENT_STATUS_OK; | |
9ae49d3d | 602 | goto end; |
bc506aa5 | 603 | |
9ae49d3d JD |
604 | error: |
605 | ret = BT_COMPONENT_STATUS_ERROR; | |
606 | end: | |
bc506aa5 | 607 | bt_put(writer_event); |
bc506aa5 | 608 | bt_put(writer_event_class); |
bc506aa5 | 609 | bt_put(writer_stream_class); |
bc506aa5 | 610 | bt_put(stream_class); |
bc506aa5 | 611 | bt_put(writer_stream); |
bc506aa5 | 612 | bt_put(stream); |
bc506aa5 | 613 | bt_put(event_class); |
bc506aa5 JD |
614 | return ret; |
615 | } |