lib: add "borrow" functions where "get" functions exist
[babeltrace.git] / include / babeltrace / ctf-ir / event-internal.h
1 #ifndef BABELTRACE_CTF_IR_EVENT_INTERNAL_H
2 #define BABELTRACE_CTF_IR_EVENT_INTERNAL_H
3
4 /*
5 * Babeltrace - CTF IR: Event internal
6 *
7 * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
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
30 #include <babeltrace/assert-pre-internal.h>
31 #include <babeltrace/babeltrace-internal.h>
32 #include <babeltrace/values.h>
33 #include <babeltrace/ctf-ir/stream-class.h>
34 #include <babeltrace/ctf-ir/stream.h>
35 #include <babeltrace/ctf-ir/packet.h>
36 #include <babeltrace/ctf-ir/fields.h>
37 #include <babeltrace/ctf-ir/fields-internal.h>
38 #include <babeltrace/ctf-ir/event-class-internal.h>
39 #include <babeltrace/ctf-ir/validation-internal.h>
40 #include <babeltrace/object-internal.h>
41 #include <babeltrace/assert-internal.h>
42 #include <glib.h>
43
44 struct bt_stream_pos;
45
46 struct bt_event_common {
47 struct bt_object base;
48 struct bt_event_class_common *class;
49 struct bt_field_common *header_field;
50 struct bt_field_common *stream_event_context_field;
51 struct bt_field_common *context_field;
52 struct bt_field_common *payload_field;
53 int frozen;
54 };
55
56 struct bt_event {
57 struct bt_event_common common;
58
59 /* Maps clock classes to bt_clock_value. */
60 GHashTable *clock_values;
61 struct bt_packet *packet;
62 };
63
64 BT_HIDDEN
65 int _bt_event_common_validate(struct bt_event_common *event);
66
67 BT_HIDDEN
68 void _bt_event_common_freeze(struct bt_event_common *event);
69
70 BT_HIDDEN
71 void _bt_event_freeze(struct bt_event *event);
72
73 #ifdef BT_DEV_MODE
74 # define bt_event_common_validate _bt_event_common_validate
75 # define bt_event_common_freeze _bt_event_common_freeze
76 # define bt_event_freeze _bt_event_freeze
77 #else
78 # define bt_event_common_validate(_event) 0
79 # define bt_event_common_freeze(_event)
80 # define bt_event_freeze(_event)
81 #endif
82
83 #define BT_ASSERT_PRE_EVENT_COMMON_HOT(_event, _name) \
84 BT_ASSERT_PRE_HOT((_event), (_name), ": +%!+_e", (_event))
85
86 static inline
87 struct bt_event_class_common *bt_event_common_borrow_class(
88 struct bt_event_common *event)
89 {
90 BT_ASSERT(event);
91 return event->class;
92 }
93
94 BT_HIDDEN
95 int bt_event_common_initialize(struct bt_event_common *event,
96 struct bt_event_class_common *event_class,
97 struct bt_clock_class *init_expected_clock_class,
98 bt_object_release_func release_func,
99 bt_validation_flag_copy_field_type_func field_type_copy_func,
100 bool must_be_in_trace,
101 int (*map_clock_classes_func)(struct bt_stream_class_common *stream_class,
102 struct bt_field_type_common *packet_context_field_type,
103 struct bt_field_type_common *event_header_field_type),
104 void *(*create_field_func)(void *));
105
106 static inline
107 struct bt_field_common *bt_event_common_borrow_payload(
108 struct bt_event_common *event)
109 {
110 struct bt_field_common *payload = NULL;
111
112 BT_ASSERT_PRE_NON_NULL(event, "Event");
113
114 if (!event->payload_field) {
115 BT_LOGV("Event has no current payload field: addr=%p, "
116 "event-class-name=\"%s\", event-class-id=%" PRId64,
117 event, bt_event_class_common_get_name(event->class),
118 bt_event_class_common_get_id(event->class));
119 goto end;
120 }
121
122 payload = event->payload_field;
123
124 end:
125 return payload;
126 }
127
128 static inline
129 int bt_event_common_set_payload(struct bt_event_common *event,
130 struct bt_field_common *payload)
131 {
132 BT_ASSERT_PRE_NON_NULL(event, "Event");
133 BT_ASSERT_PRE_EVENT_COMMON_HOT(event, "Event");
134
135 if (payload) {
136 BT_ASSERT_PRE(bt_field_type_common_compare(payload->type,
137 event->class->payload_field_type) == 0,
138 "Payload field's type is different from the "
139 "expected field type: %![event-]+_e, %![ft-]+_F, "
140 "%![expected-ft-]+_F",
141 event, payload->type,
142 event->class->payload_field_type);
143 } else {
144 BT_ASSERT_PRE(!event->class->payload_field_type,
145 "Setting no event payload field, "
146 "but event payload field type is not NULL: ",
147 "%![event-]+_e, %![payload-ft-]+_F",
148 event, event->class->payload_field_type);
149 }
150
151 bt_put(event->payload_field);
152 event->payload_field = bt_get(payload);
153 BT_LOGV("Set event's payload field: event-addr=%p, "
154 "event-class-name=\"%s\", event-class-id=%" PRId64 ", "
155 "payload-field-addr=%p",
156 event, bt_event_class_common_get_name(event->class),
157 bt_event_class_common_get_id(event->class), payload);
158 return 0;
159 }
160
161 static inline
162 struct bt_field_common *bt_event_common_borrow_header(
163 struct bt_event_common *event)
164 {
165 struct bt_field_common *header = NULL;
166
167 BT_ASSERT_PRE_NON_NULL(event, "Event");
168
169 if (!event->header_field) {
170 BT_LOGV("Event has no current header field: addr=%p, "
171 "event-class-name=\"%s\", event-class-id=%" PRId64,
172 event, bt_event_class_common_get_name(event->class),
173 bt_event_class_common_get_id(event->class));
174 goto end;
175 }
176
177 header = event->header_field;
178
179 end:
180 return header;
181 }
182
183 static inline
184 int bt_event_common_set_header(struct bt_event_common *event,
185 struct bt_field_common *header)
186 {
187 BT_ASSERT_PRE_NON_NULL(event, "Event");
188 BT_ASSERT_PRE_EVENT_COMMON_HOT(event, "Event");
189
190 /*
191 * Ensure the provided header's type matches the one registered to the
192 * stream class.
193 */
194 if (header) {
195 BT_ASSERT_PRE(bt_field_type_common_compare(header->type,
196 bt_event_class_common_borrow_stream_class(event->class)->event_header_field_type) == 0,
197 "Header field's type is different from the "
198 "expected field type: %![event-]+_e, %![ft-]+_F, "
199 "%![expected-ft-]+_F",
200 event, header->type,
201 bt_event_class_common_borrow_stream_class(event->class)->event_header_field_type);
202 } else {
203 BT_ASSERT_PRE(!bt_event_class_common_borrow_stream_class(event->class)->event_header_field_type,
204 "Setting no event header field, "
205 "but event header field type is not NULL: ",
206 "%![event-]+_e, %![header-ft-]+_F",
207 event,
208 bt_event_class_common_borrow_stream_class(event->class)->event_header_field_type);
209 }
210
211 bt_put(event->header_field);
212 event->header_field = bt_get(header);
213 BT_LOGV("Set event's header field: event-addr=%p, "
214 "event-class-name=\"%s\", event-class-id=%" PRId64 ", "
215 "header-field-addr=%p",
216 event, bt_event_class_common_get_name(event->class),
217 bt_event_class_common_get_id(event->class), header);
218 return 0;
219 }
220
221 static inline
222 struct bt_field_common *bt_event_common_borrow_context(
223 struct bt_event_common *event)
224 {
225 struct bt_field_common *context = NULL;
226
227 BT_ASSERT_PRE_NON_NULL(event, "Event");
228
229 if (!event->context_field) {
230 BT_LOGV("Event has no current context field: addr=%p, "
231 "event-class-name=\"%s\", event-class-id=%" PRId64,
232 event, bt_event_class_common_get_name(event->class),
233 bt_event_class_common_get_id(event->class));
234 goto end;
235 }
236
237 context = event->context_field;
238
239 end:
240 return context;
241 }
242
243 static inline
244 int bt_event_common_set_context(struct bt_event_common *event,
245 struct bt_field_common *context)
246 {
247 BT_ASSERT_PRE_NON_NULL(event, "Event");
248 BT_ASSERT_PRE_EVENT_COMMON_HOT(event, "Event");
249
250 if (context) {
251 BT_ASSERT_PRE(bt_field_type_common_compare(context->type,
252 event->class->context_field_type) == 0,
253 "Context field's type is different from the "
254 "expected field type: %![event-]+_e, %![ft-]+_F, "
255 "%![expected-ft-]+_F",
256 event, context->type, event->class->context_field_type);
257 } else {
258 BT_ASSERT_PRE(!event->class->context_field_type,
259 "Setting no event context field, "
260 "but event context field type is not NULL: ",
261 "%![event-]+_e, %![context-ft-]+_F",
262 event, event->class->context_field_type);
263 }
264
265 bt_put(event->context_field);
266 event->context_field = bt_get(context);
267 BT_LOGV("Set event's context field: event-addr=%p, "
268 "event-class-name=\"%s\", event-class-id=%" PRId64 ", "
269 "context-field-addr=%p",
270 event, bt_event_class_common_get_name(event->class),
271 bt_event_class_common_get_id(event->class), context);
272 return 0;
273 }
274
275 static inline
276 struct bt_field_common *bt_event_common_borrow_stream_event_context(
277 struct bt_event_common *event)
278 {
279 struct bt_field_common *stream_event_context = NULL;
280
281 BT_ASSERT_PRE_NON_NULL(event, "Event");
282
283 if (!event->stream_event_context_field) {
284 BT_LOGV("Event has no current stream event context field: addr=%p, "
285 "event-class-name=\"%s\", event-class-id=%" PRId64,
286 event, bt_event_class_common_get_name(event->class),
287 bt_event_class_common_get_id(event->class));
288 goto end;
289 }
290
291 stream_event_context = event->stream_event_context_field;
292
293 end:
294 return stream_event_context;
295 }
296
297 static inline
298 int bt_event_common_set_stream_event_context(struct bt_event_common *event,
299 struct bt_field_common *stream_event_context)
300 {
301 BT_ASSERT_PRE_NON_NULL(event, "Event");
302 BT_ASSERT_PRE_EVENT_COMMON_HOT(event, "Event");
303
304 if (stream_event_context) {
305 BT_ASSERT_PRE(bt_field_type_common_compare(stream_event_context->type,
306 bt_event_class_common_borrow_stream_class(event->class)->event_context_field_type) == 0,
307 "Stream event context field's type is different from the "
308 "expected field type: %![event-]+_e, %![ft-]+_F, "
309 "%![expected-ft-]+_F",
310 event, stream_event_context->type,
311 bt_event_class_common_borrow_stream_class(event->class)->event_context_field_type);
312 } else {
313 BT_ASSERT_PRE(!bt_event_class_common_borrow_stream_class(event->class)->event_context_field_type,
314 "Setting no stream event context field, "
315 "but stream event context field type is not NULL: ",
316 "%![event-]+_e, %![context-ft-]+_F",
317 event,
318 bt_event_class_common_borrow_stream_class(event->class)->event_context_field_type);
319 }
320
321 bt_get(stream_event_context);
322 BT_MOVE(event->stream_event_context_field, stream_event_context);
323 BT_LOGV("Set event's stream event context field: event-addr=%p, "
324 "event-class-name=\"%s\", event-class-id=%" PRId64 ", "
325 "stream-event-context-field-addr=%p",
326 event, bt_event_class_common_get_name(event->class),
327 bt_event_class_common_get_id(event->class),
328 stream_event_context);
329 return 0;
330 }
331
332 static inline
333 void bt_event_common_finalize(struct bt_object *obj)
334 {
335 struct bt_event_common *event = (void *) obj;
336
337 BT_LOGD("Destroying event: addr=%p, "
338 "event-class-name=\"%s\", event-class-id=%" PRId64,
339 event, bt_event_class_common_get_name(event->class),
340 bt_event_class_common_get_id(event->class));
341
342 if (!event->base.parent) {
343 /*
344 * Event was keeping a reference to its class since it shared no
345 * common ancestor with it to guarantee they would both have the
346 * same lifetime.
347 */
348 bt_put(event->class);
349 }
350
351 bt_put(event->header_field);
352 BT_LOGD_STR("Putting event's stream event context field.");
353 bt_put(event->stream_event_context_field);
354 BT_LOGD_STR("Putting event's context field.");
355 bt_put(event->context_field);
356 BT_LOGD_STR("Putting event's payload field.");
357 bt_put(event->payload_field);
358 BT_LOGD_STR("Putting event's packet.");
359 }
360
361 #endif /* BABELTRACE_CTF_IR_EVENT_INTERNAL_H */
This page took 0.041627 seconds and 5 git commands to generate.