lib: remove internal stream destroy listener API
[babeltrace.git] / include / babeltrace / ctf-ir / event-internal.h
CommitLineData
adc315b8
JG
1#ifndef BABELTRACE_CTF_IR_EVENT_INTERNAL_H
2#define BABELTRACE_CTF_IR_EVENT_INTERNAL_H
273b65be
JG
3
4/*
272df73e 5 * Babeltrace - CTF IR: Event internal
273b65be 6 *
de9dd397 7 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
273b65be
JG
8 *
9 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
10 *
11 * Permission is hereby granted, free of charge, to any person obtaining a copy
12 * of this software and associated documentation files (the "Software"), to deal
13 * in the Software without restriction, including without limitation the rights
14 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 * copies of the Software, and to permit persons to whom the Software is
16 * furnished to do so, subject to the following conditions:
17 *
18 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 * SOFTWARE.
28 */
29
3dca2276 30#include <babeltrace/assert-pre-internal.h>
273b65be 31#include <babeltrace/babeltrace-internal.h>
dac5c838 32#include <babeltrace/values.h>
123fbdec
JG
33#include <babeltrace/ctf-ir/stream-class.h>
34#include <babeltrace/ctf-ir/stream.h>
26e21a82 35#include <babeltrace/ctf-ir/stream-internal.h>
5c3b707d 36#include <babeltrace/ctf-ir/packet.h>
6c677fb5 37#include <babeltrace/ctf-ir/packet-internal.h>
3dca2276
PP
38#include <babeltrace/ctf-ir/fields.h>
39#include <babeltrace/ctf-ir/fields-internal.h>
40#include <babeltrace/ctf-ir/event-class-internal.h>
6c677fb5 41#include <babeltrace/ctf-ir/clock-value-internal.h>
312c056a 42#include <babeltrace/ctf-ir/field-wrapper-internal.h>
3dca2276 43#include <babeltrace/ctf-ir/validation-internal.h>
83509119 44#include <babeltrace/object-internal.h>
f6ccaed9 45#include <babeltrace/assert-internal.h>
273b65be
JG
46#include <glib.h>
47
50842bdc 48struct bt_stream_pos;
dc3fffef 49
3dca2276 50struct bt_event_common {
83509119 51 struct bt_object base;
3dca2276 52 struct bt_event_class_common *class;
312c056a 53 struct bt_field_wrapper *header_field;
3dca2276
PP
54 struct bt_field_common *stream_event_context_field;
55 struct bt_field_common *context_field;
56 struct bt_field_common *payload_field;
57 int frozen;
58};
59
60struct bt_event {
61 struct bt_event_common common;
62
50842bdc 63 /* Maps clock classes to bt_clock_value. */
1556a1af 64 GHashTable *clock_values;
3dca2276 65 struct bt_packet *packet;
273b65be
JG
66};
67
273b65be 68BT_HIDDEN
3dca2276 69int _bt_event_common_validate(struct bt_event_common *event);
273b65be 70
4ce9f9d0 71BT_HIDDEN
6c677fb5
PP
72void _bt_event_common_set_is_frozen(struct bt_event_common *event,
73 bool is_frozen);
4ce9f9d0 74
f6ccaed9 75BT_HIDDEN
6c677fb5 76void _bt_event_set_is_frozen(struct bt_event *event, bool is_frozen);
f6ccaed9
PP
77
78#ifdef BT_DEV_MODE
6c677fb5
PP
79# define bt_event_common_validate _bt_event_common_validate
80# define bt_event_common_set_is_frozen _bt_event_common_set_is_frozen
81# define bt_event_set_is_frozen _bt_event_set_is_frozen
f6ccaed9 82#else
6c677fb5
PP
83# define bt_event_common_validate(_event) 0
84# define bt_event_common_set_is_frozen(_event, _is_frozen)
85# define bt_event_set_is_frozen(_event, _is_frozen)
f6ccaed9
PP
86#endif
87
3dca2276
PP
88#define BT_ASSERT_PRE_EVENT_COMMON_HOT(_event, _name) \
89 BT_ASSERT_PRE_HOT((_event), (_name), ": +%!+_e", (_event))
90
dc3fffef 91static inline
3dca2276
PP
92struct bt_event_class_common *bt_event_common_borrow_class(
93 struct bt_event_common *event)
dc3fffef 94{
f6ccaed9 95 BT_ASSERT(event);
3dca2276
PP
96 return event->class;
97}
98
2dd764c1
PP
99typedef void *(*create_field_func)(void *);
100typedef void (*release_field_func)(void *);
101typedef void *(*create_header_field_func)(void *, void *);
102typedef void (*release_header_field_func)(void *, void *);
103
3dca2276
PP
104BT_HIDDEN
105int bt_event_common_initialize(struct bt_event_common *event,
106 struct bt_event_class_common *event_class,
107 struct bt_clock_class *init_expected_clock_class,
3fea54f6 108 bool is_shared_with_parent, bt_object_release_func release_func,
3dca2276
PP
109 bt_validation_flag_copy_field_type_func field_type_copy_func,
110 bool must_be_in_trace,
111 int (*map_clock_classes_func)(struct bt_stream_class_common *stream_class,
112 struct bt_field_type_common *packet_context_field_type,
113 struct bt_field_type_common *event_header_field_type),
2dd764c1
PP
114 create_field_func create_field_func,
115 release_field_func release_field_func,
116 create_header_field_func create_header_field_func,
117 release_header_field_func release_header_field_func);
3dca2276
PP
118
119static inline
094ff7c0 120struct bt_field_common *bt_event_common_borrow_payload(
3dca2276
PP
121 struct bt_event_common *event)
122{
123 struct bt_field_common *payload = NULL;
124
125 BT_ASSERT_PRE_NON_NULL(event, "Event");
126
127 if (!event->payload_field) {
128 BT_LOGV("Event has no current payload field: addr=%p, "
129 "event-class-name=\"%s\", event-class-id=%" PRId64,
130 event, bt_event_class_common_get_name(event->class),
131 bt_event_class_common_get_id(event->class));
132 goto end;
133 }
134
135 payload = event->payload_field;
3dca2276
PP
136
137end:
138 return payload;
139}
140
3dca2276 141static inline
094ff7c0 142struct bt_field_common *bt_event_common_borrow_header(
3dca2276
PP
143 struct bt_event_common *event)
144{
145 struct bt_field_common *header = NULL;
146
147 BT_ASSERT_PRE_NON_NULL(event, "Event");
148
149 if (!event->header_field) {
150 BT_LOGV("Event has no current header field: addr=%p, "
151 "event-class-name=\"%s\", event-class-id=%" PRId64,
152 event, bt_event_class_common_get_name(event->class),
153 bt_event_class_common_get_id(event->class));
154 goto end;
155 }
156
312c056a 157 header = event->header_field->field;
3dca2276
PP
158
159end:
160 return header;
161}
162
3dca2276 163static inline
094ff7c0 164struct bt_field_common *bt_event_common_borrow_context(
3dca2276
PP
165 struct bt_event_common *event)
166{
167 struct bt_field_common *context = NULL;
168
169 BT_ASSERT_PRE_NON_NULL(event, "Event");
170
171 if (!event->context_field) {
172 BT_LOGV("Event has no current context field: addr=%p, "
173 "event-class-name=\"%s\", event-class-id=%" PRId64,
174 event, bt_event_class_common_get_name(event->class),
175 bt_event_class_common_get_id(event->class));
176 goto end;
177 }
178
179 context = event->context_field;
3dca2276
PP
180
181end:
182 return context;
183}
184
3dca2276 185static inline
094ff7c0 186struct bt_field_common *bt_event_common_borrow_stream_event_context(
3dca2276
PP
187 struct bt_event_common *event)
188{
189 struct bt_field_common *stream_event_context = NULL;
190
191 BT_ASSERT_PRE_NON_NULL(event, "Event");
192
193 if (!event->stream_event_context_field) {
194 BT_LOGV("Event has no current stream event context field: addr=%p, "
195 "event-class-name=\"%s\", event-class-id=%" PRId64,
196 event, bt_event_class_common_get_name(event->class),
197 bt_event_class_common_get_id(event->class));
198 goto end;
199 }
200
201 stream_event_context = event->stream_event_context_field;
202
203end:
094ff7c0 204 return stream_event_context;
3dca2276
PP
205}
206
207static inline
312c056a
PP
208void bt_event_common_finalize(struct bt_object *obj,
209 void (*field_release_func)(void *),
210 void (*header_field_release_func)(void *, struct bt_event_common *))
3dca2276
PP
211{
212 struct bt_event_common *event = (void *) obj;
213
214 BT_LOGD("Destroying event: addr=%p, "
215 "event-class-name=\"%s\", event-class-id=%" PRId64,
312c056a
PP
216 event,
217 event->class ? bt_event_class_common_get_name(event->class) : NULL,
218 event->class ? bt_event_class_common_get_id(event->class) : INT64_C(-1));
219
220 if (event->header_field) {
221 BT_LOGD_STR("Releasing event's header field.");
222 header_field_release_func(event->header_field, event);
223 }
224
225 if (event->stream_event_context_field) {
226 BT_LOGD_STR("Releasing event's stream event context field.");
227 field_release_func(event->stream_event_context_field);
228 }
229
230 if (event->context_field) {
231 BT_LOGD_STR("Releasing event's context field.");
232 field_release_func(event->context_field);
233 }
234
235 if (event->payload_field) {
236 BT_LOGD_STR("Releasing event's payload field.");
237 field_release_func(event->payload_field);
238 }
3dca2276 239
312c056a
PP
240 /*
241 * Leave this after calling header_field_release_func() because
242 * this function receives the event object and could need its
243 * class to perform some cleanup.
244 */
3dca2276
PP
245 if (!event->base.parent) {
246 /*
247 * Event was keeping a reference to its class since it shared no
248 * common ancestor with it to guarantee they would both have the
249 * same lifetime.
250 */
251 bt_put(event->class);
252 }
dc3fffef
PP
253}
254
6c677fb5
PP
255BT_UNUSED
256static inline
257void _bt_event_reset_dev_mode(struct bt_event *event)
258{
259 GHashTableIter iter;
260 gpointer key, value;
312c056a 261
6c677fb5 262 BT_ASSERT(event);
312c056a 263
6c677fb5
PP
264 if (event->common.header_field) {
265 bt_field_common_set_is_frozen_recursive(
266 event->common.header_field->field, false);
267 bt_field_common_reset_recursive(
268 event->common.header_field->field);
269 }
270
271 if (event->common.stream_event_context_field) {
272 bt_field_common_set_is_frozen_recursive(
273 event->common.stream_event_context_field, false);
274 bt_field_common_reset_recursive(
275 event->common.stream_event_context_field);
276 }
277
278 if (event->common.context_field) {
279 bt_field_common_set_is_frozen_recursive(
280 event->common.context_field, false);
281 bt_field_common_reset_recursive(event->common.context_field);
282 }
283
284 if (event->common.payload_field) {
285 bt_field_common_set_is_frozen_recursive(
286 event->common.payload_field, false);
287 bt_field_common_reset_recursive(event->common.payload_field);
288 }
289
290 g_hash_table_iter_init(&iter, event->clock_values);
291 while (g_hash_table_iter_next(&iter, &key, &value)) {
292 struct bt_clock_value *clock_value = value;
293
294 BT_ASSERT(clock_value);
295 bt_clock_value_reset(clock_value);
296 bt_clock_value_set_is_frozen(clock_value, false);
297 }
298}
299
300#ifdef BT_DEV_MODE
301# define bt_event_reset_dev_mode _bt_event_reset_dev_mode
302#else
303# define bt_event_reset_dev_mode(_x)
304#endif
312c056a
PP
305
306BT_HIDDEN
307void bt_event_destroy(struct bt_event *event);
308
6c677fb5
PP
309static inline
310void bt_event_reset(struct bt_event *event)
311{
312 BT_ASSERT(event);
313 bt_event_set_is_frozen(event, false);
314 bt_event_reset_dev_mode(event);
315 bt_object_put_no_null_check(&event->packet->base);
316 event->packet = NULL;
317}
318
319static inline
320void bt_event_recycle(struct bt_event *event)
321{
322 struct bt_event_class *event_class;
323
324 BT_ASSERT(event);
325 BT_LIB_LOGD("Recycling event: %!+e", event);
326
327 /*
328 * Those are the important ordered steps:
329 *
330 * 1. Reset the event object (put any permanent reference it
331 * has, unfreeze it and its fields in developer mode, etc.),
332 * but do NOT put its class's reference. This event class
333 * contains the pool to which we're about to recycle this
334 * event object, so we must guarantee its existence thanks
335 * to this existing reference.
336 *
337 * 2. Move the event class reference to our `event_class`
338 * variable so that we can set the event's class member
339 * to NULL before recycling it. We CANNOT do this after
340 * we put the event class reference because this bt_put()
341 * could destroy the event class, also destroying its
342 * event pool, thus also destroying our event object (this
343 * would result in an invalid write access).
344 *
345 * 3. Recycle the event object.
346 *
347 * 4. Put our event class reference.
348 */
349 bt_event_reset(event);
350 event_class = BT_FROM_COMMON(event->common.class);
351 BT_ASSERT(event_class);
352 event->common.class = NULL;
353 bt_object_pool_recycle_object(&event_class->event_pool, event);
354 bt_object_put_no_null_check(&event_class->common.base);
355}
356
357static inline
358void bt_event_set_packet(struct bt_event *event, struct bt_packet *packet)
359{
360 BT_ASSERT_PRE_NON_NULL(event, "Event");
361 BT_ASSERT_PRE_NON_NULL(packet, "Packet");
362 BT_ASSERT_PRE_EVENT_COMMON_HOT(BT_TO_COMMON(event), "Event");
26e21a82
PP
363 BT_ASSERT_PRE(bt_event_class_borrow_stream_class(
364 BT_FROM_COMMON(event->common.class)) ==
365 BT_FROM_COMMON(packet->stream->common.stream_class),
366 "Packet's stream class and event's stream class differ: "
367 "%![event-]+e, %![packet-]+a",
368 event, packet);
369
6c677fb5
PP
370 BT_ASSERT(!event->packet);
371 event->packet = packet;
372 bt_object_get_no_null_check_no_parent_check(&event->packet->base);
373 BT_LOGV("Set event's packet: event-addr=%p, "
374 "event-class-name=\"%s\", event-class-id=%" PRId64 ", "
375 "packet-addr=%p",
376 event, bt_event_class_common_get_name(event->common.class),
377 bt_event_class_common_get_id(event->common.class), packet);
378}
379
380static inline
381struct bt_event *bt_event_create(struct bt_event_class *event_class,
382 struct bt_packet *packet)
383{
384 struct bt_event *event = NULL;
385
386 BT_ASSERT(event_class);
387 event = bt_object_pool_create_object(&event_class->event_pool);
388 if (unlikely(!event)) {
389 BT_LIB_LOGE("Cannot allocate one event from event class's event pool: "
390 "%![event-class-]+E", event_class);
391 goto end;
392 }
393
394 if (unlikely(!event->common.class)) {
395 event->common.class = BT_TO_COMMON(event_class);
396 bt_object_get_no_null_check(&event_class->common.base);
397 }
398
399 BT_ASSERT(packet);
400 bt_event_set_packet(event, packet);
401 goto end;
402
403end:
404 return event;
405}
406
312c056a 407BT_HIDDEN
6c677fb5 408struct bt_event *bt_event_new(struct bt_event_class *event_class);
312c056a 409
adc315b8 410#endif /* BABELTRACE_CTF_IR_EVENT_INTERNAL_H */
This page took 0.061214 seconds and 4 git commands to generate.