src.ctf.lttng-live: use `_APPEND_CAUSE` variants of logging macros
[babeltrace.git] / src / plugins / text / details / obj-lifetime-mgmt.c
CommitLineData
a0bcd369
PP
1/*
2 * Copyright 2019 Philippe Proulx <pproulx@efficios.com>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
21 */
22
969c1d8a
FD
23#include <stdbool.h>
24
a0bcd369
PP
25#include <babeltrace2/babeltrace.h>
26
27#include "common/common.h"
28#include "common/assert.h"
29#include "compat/glib.h"
30
31#include "details.h"
32#include "write.h"
33#include "obj-lifetime-mgmt.h"
34
35static
36void trace_class_destruction_listener(const bt_trace_class *tc, void *data)
37{
38 struct details_comp *details_comp = data;
39
40 BT_ASSERT(details_comp);
41 BT_ASSERT(details_comp->meta);
42
43 /* Remove from hash table, which also destroys the value */
44 g_hash_table_remove(details_comp->meta, tc);
45}
46
47static
48struct details_trace_class_meta *borrow_trace_class_meta(
49 struct details_write_ctx *ctx, const bt_trace_class *tc)
50{
51 struct details_trace_class_meta *details_tc_meta;
52
ec4a3354
PP
53 BT_ASSERT_DBG(ctx->details_comp->cfg.with_meta);
54 BT_ASSERT_DBG(ctx->details_comp->meta);
a0bcd369
PP
55 details_tc_meta = g_hash_table_lookup(ctx->details_comp->meta, tc);
56 if (!details_tc_meta) {
57 /* Not found: create one */
58 details_tc_meta = details_create_details_trace_class_meta();
59 if (!details_tc_meta) {
60 goto error;
61 }
62
63 /* Register trace class destruction listener */
64 if (bt_trace_class_add_destruction_listener(tc,
65 trace_class_destruction_listener,
66 ctx->details_comp,
67 &details_tc_meta->tc_destruction_listener_id)) {
68 goto error;
69 }
70
71 /* Insert into hash table (becomes the owner) */
72 g_hash_table_insert(ctx->details_comp->meta, (void *) tc,
73 details_tc_meta);
74 }
75
76 goto end;
77
78error:
79 details_destroy_details_trace_class_meta(details_tc_meta);
80 details_tc_meta = NULL;
81
82end:
83 return details_tc_meta;
84}
85
86BT_HIDDEN
87bool details_need_to_write_meta_object(struct details_write_ctx *ctx,
88 const bt_trace_class *tc, const void *obj)
89{
90 bool need_to_write;
91 struct details_trace_class_meta *details_tc_meta;
92
93 if (!ctx->details_comp->cfg.with_meta) {
94 need_to_write = false;
95 goto end;
96 }
97
ec4a3354 98 BT_ASSERT_DBG(ctx->details_comp->meta);
a0bcd369 99 details_tc_meta = g_hash_table_lookup(ctx->details_comp->meta, tc);
ec4a3354 100 BT_ASSERT_DBG(details_tc_meta);
a0bcd369 101 need_to_write =
8e01f2d9 102 !g_hash_table_lookup(details_tc_meta->objects, obj);
a0bcd369
PP
103
104end:
105 return need_to_write;
106}
107
108BT_HIDDEN
109void details_did_write_meta_object(struct details_write_ctx *ctx,
110 const bt_trace_class *tc, const void *obj)
111{
112 struct details_trace_class_meta *details_tc_meta;
113
114 BT_ASSERT(ctx->details_comp->cfg.with_meta);
115 details_tc_meta = borrow_trace_class_meta(ctx, tc);
116 BT_ASSERT(details_tc_meta);
117 g_hash_table_insert(details_tc_meta->objects, (gpointer) obj,
118 GUINT_TO_POINTER(1));
119}
120
121BT_HIDDEN
122bool details_need_to_write_trace_class(struct details_write_ctx *ctx,
123 const bt_trace_class *tc)
124{
125 struct details_trace_class_meta *details_tc_meta;
126 bool need_to_write;
127
128 if (!ctx->details_comp->cfg.with_meta) {
129 need_to_write = false;
130 goto end;
131 }
132
ec4a3354 133 BT_ASSERT_DBG(ctx->details_comp->meta);
a0bcd369 134 details_tc_meta = g_hash_table_lookup(ctx->details_comp->meta, tc);
8e01f2d9 135 need_to_write = !details_tc_meta;
a0bcd369
PP
136
137end:
138 return need_to_write;
139}
140
141BT_HIDDEN
142int details_did_write_trace_class(struct details_write_ctx *ctx,
143 const bt_trace_class *tc)
144{
145 int ret = 0;
146 struct details_trace_class_meta *details_tc_meta;
147
148 BT_ASSERT(ctx->details_comp->cfg.with_meta);
149
150 /* borrow_trace_class_meta() creates an entry if none exists */
151 details_tc_meta = borrow_trace_class_meta(ctx, tc);
152 if (!details_tc_meta) {
153 ret = -1;
154 }
155
156 return ret;
157}
158
159static
160void trace_destruction_listener(const bt_trace *trace, void *data)
161{
162 struct details_comp *details_comp = data;
163
164 BT_ASSERT(details_comp);
165 BT_ASSERT(details_comp->traces);
166
167 /* Remove from hash table, which also destroys the value */
168 g_hash_table_remove(details_comp->traces, trace);
169}
170
171static
172struct details_trace *create_details_trace(uint64_t unique_id)
173{
174 struct details_trace *details_trace = g_new0(struct details_trace, 1);
175
176 if (!details_trace) {
177 goto end;
178 }
179
180 details_trace->unique_id = unique_id;
181 details_trace->trace_destruction_listener_id = UINT64_C(-1);
182
183end:
184 return details_trace;
185}
186
187
188BT_HIDDEN
189int details_trace_unique_id(struct details_write_ctx *ctx,
190 const bt_trace *trace, uint64_t *unique_id)
191{
192 int ret = 0;
193 struct details_trace *details_trace = NULL;
194
ec4a3354
PP
195 BT_ASSERT_DBG(unique_id);
196 BT_ASSERT_DBG(ctx->details_comp->traces);
a0bcd369
PP
197 if (!bt_g_hash_table_contains(ctx->details_comp->traces,
198 trace)) {
199 /* Not found: create one */
200 *unique_id = ctx->details_comp->next_unique_trace_id;
201 details_trace = create_details_trace(*unique_id);
202 if (!details_trace) {
203 goto error;
204 }
205
206 ctx->details_comp->next_unique_trace_id++;
207
208 /* Register trace destruction listener if there's none */
209 if (bt_trace_add_destruction_listener(trace,
210 trace_destruction_listener,
211 ctx->details_comp,
212 &details_trace->trace_destruction_listener_id)) {
213 goto error;
214 }
215
216 BT_ASSERT(details_trace->trace_destruction_listener_id !=
217 UINT64_C(-1));
218
219 /* Move to hash table */
220 g_hash_table_insert(ctx->details_comp->traces, (gpointer) trace,
221 details_trace);
222 details_trace = NULL;
223 } else {
224 /* Found */
225 details_trace = g_hash_table_lookup(
226 ctx->details_comp->traces, trace);
227 *unique_id = details_trace->unique_id;
228 details_trace = NULL;
229 }
230
231 goto end;
232
233error:
234 ret = -1;
235
236end:
be1b2e7e 237 g_free(details_trace);
a0bcd369
PP
238
239 return ret;
240}
This page took 0.050038 seconds and 4 git commands to generate.