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 JD |
282 | struct bt_ctf_stream_class *stream_class = NULL; |
283 | struct bt_ctf_writer *ctf_writer = NULL; | |
284 | struct bt_ctf_stream *writer_stream = NULL; | |
bc506aa5 JD |
285 | |
286 | stream_class = bt_ctf_stream_get_class(stream); | |
287 | if (!stream_class) { | |
bc506aa5 JD |
288 | fprintf(writer_component->err, "[error] %s in %s:%d\n", |
289 | __func__, __FILE__, __LINE__); | |
9ae49d3d | 290 | goto error; |
bc506aa5 JD |
291 | } |
292 | ||
bc506aa5 | 293 | writer_stream = lookup_stream(writer_component, stream); |
9ae49d3d | 294 | if (!writer_stream) { |
f3168545 JD |
295 | struct fs_writer *fs_writer; |
296 | ||
297 | fs_writer = get_fs_writer(writer_component, stream_class); | |
298 | if (!fs_writer) { | |
299 | fprintf(writer_component->err, "[error] %s in %s:%d\n", | |
300 | __func__, __FILE__, __LINE__); | |
301 | goto error; | |
302 | } | |
303 | ctf_writer = bt_get(fs_writer->writer); | |
bc506aa5 JD |
304 | writer_stream = insert_new_stream(writer_component, ctf_writer, |
305 | stream_class, stream); | |
f3168545 JD |
306 | if (!writer_stream) { |
307 | fprintf(writer_component->err, "[error] %s in %s:%d\n", | |
308 | __func__, __FILE__, __LINE__); | |
309 | goto error; | |
310 | } | |
311 | fs_writer->active_streams++; | |
bc506aa5 | 312 | } |
9ae49d3d JD |
313 | bt_get(writer_stream); |
314 | ||
315 | goto end; | |
bc506aa5 | 316 | |
9ae49d3d JD |
317 | error: |
318 | BT_PUT(writer_stream); | |
319 | end: | |
bc506aa5 | 320 | bt_put(ctf_writer); |
bc506aa5 | 321 | bt_put(stream_class); |
bc506aa5 JD |
322 | return writer_stream; |
323 | } | |
324 | ||
f3168545 JD |
325 | BT_HIDDEN |
326 | enum bt_component_status writer_close( | |
327 | struct writer_component *writer_component, | |
328 | struct fs_writer *fs_writer, | |
329 | struct bt_ctf_trace *trace) | |
330 | { | |
331 | enum bt_component_status ret = BT_COMPONENT_STATUS_OK; | |
332 | ||
333 | if (fs_writer->static_listener_id > 0) { | |
334 | bt_ctf_trace_remove_is_static_listener(trace, | |
335 | fs_writer->static_listener_id); | |
336 | } | |
337 | g_hash_table_remove(writer_component->trace_map, trace); | |
338 | return ret; | |
339 | } | |
340 | ||
341 | BT_HIDDEN | |
342 | enum bt_component_status writer_stream_end( | |
343 | struct writer_component *writer_component, | |
344 | struct bt_ctf_stream *stream) | |
345 | { | |
346 | struct bt_ctf_stream_class *stream_class = NULL; | |
347 | struct fs_writer *fs_writer; | |
348 | struct bt_ctf_trace *trace = NULL; | |
349 | enum bt_component_status ret = BT_COMPONENT_STATUS_OK; | |
350 | ||
351 | g_hash_table_remove(writer_component->stream_map, stream); | |
352 | ||
353 | stream_class = bt_ctf_stream_get_class(stream); | |
354 | if (!stream_class) { | |
355 | fprintf(writer_component->err, "[error] %s in %s:%d\n", | |
356 | __func__, __FILE__, __LINE__); | |
357 | goto error; | |
358 | } | |
359 | ||
360 | fs_writer = get_fs_writer(writer_component, stream_class); | |
361 | if (!fs_writer) { | |
362 | fprintf(writer_component->err, "[error] %s in %s:%d\n", | |
363 | __func__, __FILE__, __LINE__); | |
364 | goto error; | |
365 | } | |
366 | ||
367 | assert(fs_writer->active_streams > 0); | |
368 | fs_writer->active_streams--; | |
369 | if (fs_writer->active_streams == 0 && fs_writer->trace_static) { | |
370 | trace = bt_ctf_stream_class_get_trace(stream_class); | |
371 | if (!trace) { | |
372 | fprintf(writer_component->err, "[error] %s in %s:%d\n", | |
373 | __func__, __FILE__, __LINE__); | |
374 | goto error; | |
375 | } | |
376 | ret = writer_close(writer_component, fs_writer, trace); | |
377 | } | |
378 | ||
379 | goto end; | |
380 | ||
381 | error: | |
382 | ret = BT_COMPONENT_STATUS_ERROR; | |
383 | end: | |
384 | BT_PUT(trace); | |
385 | BT_PUT(stream_class); | |
386 | return ret; | |
387 | } | |
388 | ||
bc506aa5 JD |
389 | BT_HIDDEN |
390 | enum bt_component_status writer_new_packet( | |
391 | struct writer_component *writer_component, | |
392 | struct bt_ctf_packet *packet) | |
393 | { | |
9ae49d3d JD |
394 | struct bt_ctf_stream *stream = NULL, *writer_stream = NULL; |
395 | struct bt_ctf_field *writer_packet_context = NULL; | |
bc506aa5 | 396 | enum bt_component_status ret = BT_COMPONENT_STATUS_OK; |
b2f1f465 | 397 | int int_ret; |
bc506aa5 JD |
398 | |
399 | stream = bt_ctf_packet_get_stream(packet); | |
400 | if (!stream) { | |
bc506aa5 JD |
401 | fprintf(writer_component->err, "[error] %s in %s:%d\n", |
402 | __func__, __FILE__, __LINE__); | |
9ae49d3d | 403 | goto error; |
bc506aa5 JD |
404 | } |
405 | ||
bc506aa5 JD |
406 | writer_stream = get_writer_stream(writer_component, packet, stream); |
407 | if (!writer_stream) { | |
bc506aa5 JD |
408 | fprintf(writer_component->err, "[error] %s in %s:%d\n", |
409 | __func__, __FILE__, __LINE__); | |
9ae49d3d | 410 | goto error; |
bc506aa5 | 411 | } |
9ae49d3d | 412 | BT_PUT(stream); |
bc506aa5 | 413 | |
b2f1f465 | 414 | writer_packet_context = ctf_copy_packet_context(writer_component->err, |
ab80adac | 415 | packet, writer_stream, 1); |
b2f1f465 | 416 | if (!writer_packet_context) { |
91b73004 JD |
417 | fprintf(writer_component->err, "[error] %s in %s:%d\n", |
418 | __func__, __FILE__, __LINE__); | |
9ae49d3d | 419 | goto error; |
bc506aa5 JD |
420 | } |
421 | ||
b2f1f465 JD |
422 | int_ret = bt_ctf_stream_set_packet_context(writer_stream, |
423 | writer_packet_context); | |
424 | if (int_ret < 0) { | |
b2f1f465 JD |
425 | fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__, |
426 | __FILE__, __LINE__); | |
9ae49d3d | 427 | goto error; |
b2f1f465 | 428 | } |
9ae49d3d JD |
429 | BT_PUT(writer_stream); |
430 | BT_PUT(writer_packet_context); | |
b2f1f465 | 431 | |
9ae49d3d | 432 | goto end; |
bc506aa5 | 433 | |
9ae49d3d JD |
434 | error: |
435 | ret = BT_COMPONENT_STATUS_ERROR; | |
436 | end: | |
437 | bt_put(writer_stream); | |
b2f1f465 | 438 | bt_put(writer_packet_context); |
91b73004 | 439 | bt_put(stream); |
bc506aa5 JD |
440 | return ret; |
441 | } | |
442 | ||
443 | BT_HIDDEN | |
444 | enum bt_component_status writer_close_packet( | |
445 | struct writer_component *writer_component, | |
446 | struct bt_ctf_packet *packet) | |
447 | { | |
9ae49d3d | 448 | struct bt_ctf_stream *stream = NULL, *writer_stream = NULL; |
bc506aa5 JD |
449 | enum bt_component_status ret; |
450 | ||
451 | stream = bt_ctf_packet_get_stream(packet); | |
452 | if (!stream) { | |
bc506aa5 JD |
453 | fprintf(writer_component->err, "[error] %s in %s:%d\n", |
454 | __func__, __FILE__, __LINE__); | |
9ae49d3d | 455 | goto error; |
bc506aa5 JD |
456 | } |
457 | ||
458 | writer_stream = lookup_stream(writer_component, stream); | |
459 | if (!writer_stream) { | |
bc506aa5 JD |
460 | fprintf(writer_component->err, "[error] %s in %s:%d\n", |
461 | __func__, __FILE__, __LINE__); | |
9ae49d3d | 462 | goto error; |
bc506aa5 | 463 | } |
9ae49d3d | 464 | BT_PUT(stream); |
bc506aa5 | 465 | |
9ae49d3d | 466 | bt_get(writer_stream); |
bc506aa5 | 467 | |
bc506aa5 JD |
468 | ret = bt_ctf_stream_flush(writer_stream); |
469 | if (ret < 0) { | |
470 | fprintf(writer_component->err, | |
471 | "[error] Failed to flush packet\n"); | |
9ae49d3d | 472 | goto error; |
bc506aa5 | 473 | } |
9ae49d3d | 474 | BT_PUT(writer_stream); |
bc506aa5 JD |
475 | |
476 | ret = BT_COMPONENT_STATUS_OK; | |
9ae49d3d | 477 | goto end; |
bc506aa5 | 478 | |
9ae49d3d JD |
479 | error: |
480 | ret = BT_COMPONENT_STATUS_ERROR; | |
481 | end: | |
bc506aa5 | 482 | bt_put(writer_stream); |
bc506aa5 | 483 | bt_put(stream); |
bc506aa5 JD |
484 | return ret; |
485 | } | |
486 | ||
bc506aa5 JD |
487 | BT_HIDDEN |
488 | enum bt_component_status writer_output_event( | |
489 | struct writer_component *writer_component, | |
490 | struct bt_ctf_event *event) | |
491 | { | |
492 | enum bt_component_status ret; | |
9ae49d3d JD |
493 | struct bt_ctf_event_class *event_class = NULL, *writer_event_class = NULL; |
494 | struct bt_ctf_stream *stream = NULL, *writer_stream = NULL; | |
495 | struct bt_ctf_stream_class *stream_class = NULL, *writer_stream_class = NULL; | |
496 | struct bt_ctf_event *writer_event = NULL; | |
bc506aa5 JD |
497 | const char *event_name; |
498 | int int_ret; | |
499 | ||
500 | event_class = bt_ctf_event_get_class(event); | |
501 | if (!event_class) { | |
bc506aa5 JD |
502 | fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__, |
503 | __FILE__, __LINE__); | |
9ae49d3d | 504 | goto error; |
bc506aa5 JD |
505 | } |
506 | ||
507 | event_name = bt_ctf_event_class_get_name(event_class); | |
508 | if (!event_name) { | |
bc506aa5 JD |
509 | fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__, |
510 | __FILE__, __LINE__); | |
9ae49d3d | 511 | goto error; |
bc506aa5 | 512 | } |
bc506aa5 JD |
513 | |
514 | stream = bt_ctf_event_get_stream(event); | |
515 | if (!stream) { | |
bc506aa5 JD |
516 | fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__, |
517 | __FILE__, __LINE__); | |
9ae49d3d | 518 | goto error; |
bc506aa5 JD |
519 | } |
520 | ||
521 | writer_stream = lookup_stream(writer_component, stream); | |
522 | if (!writer_stream || !bt_get(writer_stream)) { | |
bc506aa5 JD |
523 | fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__, |
524 | __FILE__, __LINE__); | |
9ae49d3d | 525 | goto error; |
bc506aa5 JD |
526 | } |
527 | ||
528 | stream_class = bt_ctf_event_class_get_stream_class(event_class); | |
529 | if (!stream_class) { | |
bc506aa5 JD |
530 | fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__, |
531 | __FILE__, __LINE__); | |
9ae49d3d | 532 | goto error; |
bc506aa5 JD |
533 | } |
534 | ||
535 | writer_stream_class = g_hash_table_lookup( | |
536 | writer_component->stream_class_map, | |
537 | (gpointer) stream_class); | |
538 | if (!writer_stream_class || !bt_get(writer_stream_class)) { | |
bc506aa5 JD |
539 | fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__, |
540 | __FILE__, __LINE__); | |
9ae49d3d | 541 | goto error; |
bc506aa5 JD |
542 | } |
543 | ||
544 | writer_event_class = get_event_class(writer_component, | |
545 | writer_stream_class, event_class); | |
546 | if (!writer_event_class) { | |
af34e875 JD |
547 | writer_event_class = ctf_copy_event_class(writer_component->err, |
548 | event_class); | |
549 | if (!writer_event_class) { | |
af34e875 JD |
550 | fprintf(writer_component->err, "[error] %s in %s:%d\n", |
551 | __func__, __FILE__, __LINE__); | |
9ae49d3d | 552 | goto error; |
af34e875 JD |
553 | } |
554 | int_ret = bt_ctf_stream_class_add_event_class( | |
555 | writer_stream_class, writer_event_class); | |
556 | if (int_ret) { | |
af34e875 JD |
557 | fprintf(writer_component->err, "[error] %s in %s:%d\n", |
558 | __func__, __FILE__, __LINE__); | |
9ae49d3d | 559 | goto error; |
af34e875 | 560 | } |
bc506aa5 JD |
561 | } |
562 | ||
b2f1f465 JD |
563 | writer_event = ctf_copy_event(writer_component->err, event, |
564 | writer_event_class, true); | |
bc506aa5 | 565 | if (!writer_event) { |
bc506aa5 JD |
566 | fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__, |
567 | __FILE__, __LINE__); | |
568 | fprintf(writer_component->err, "[error] Failed to copy event %s\n", | |
569 | bt_ctf_event_class_get_name(writer_event_class)); | |
9ae49d3d | 570 | goto error; |
bc506aa5 JD |
571 | } |
572 | ||
573 | int_ret = bt_ctf_stream_append_event(writer_stream, writer_event); | |
574 | if (int_ret < 0) { | |
bc506aa5 JD |
575 | fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__, |
576 | __FILE__, __LINE__); | |
577 | fprintf(writer_component->err, "[error] Failed to append event %s\n", | |
578 | bt_ctf_event_class_get_name(writer_event_class)); | |
9ae49d3d | 579 | goto error; |
bc506aa5 JD |
580 | } |
581 | ||
582 | ret = BT_COMPONENT_STATUS_OK; | |
9ae49d3d | 583 | goto end; |
bc506aa5 | 584 | |
9ae49d3d JD |
585 | error: |
586 | ret = BT_COMPONENT_STATUS_ERROR; | |
587 | end: | |
bc506aa5 | 588 | bt_put(writer_event); |
bc506aa5 | 589 | bt_put(writer_event_class); |
bc506aa5 | 590 | bt_put(writer_stream_class); |
bc506aa5 | 591 | bt_put(stream_class); |
bc506aa5 | 592 | bt_put(writer_stream); |
bc506aa5 | 593 | bt_put(stream); |
bc506aa5 | 594 | bt_put(event_class); |
bc506aa5 JD |
595 | return ret; |
596 | } |