Cleanup: add `#include <stdbool.h>` whenever `bool` type is used
[babeltrace.git] / src / plugins / text / details / obj-lifetime-mgmt.c
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
23 #include <stdbool.h>
24
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
35 static
36 void 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
47 static
48 struct 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
53 BT_ASSERT_DBG(ctx->details_comp->cfg.with_meta);
54 BT_ASSERT_DBG(ctx->details_comp->meta);
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
78 error:
79 details_destroy_details_trace_class_meta(details_tc_meta);
80 details_tc_meta = NULL;
81
82 end:
83 return details_tc_meta;
84 }
85
86 BT_HIDDEN
87 bool 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
98 BT_ASSERT_DBG(ctx->details_comp->meta);
99 details_tc_meta = g_hash_table_lookup(ctx->details_comp->meta, tc);
100 BT_ASSERT_DBG(details_tc_meta);
101 need_to_write =
102 !g_hash_table_lookup(details_tc_meta->objects, obj);
103
104 end:
105 return need_to_write;
106 }
107
108 BT_HIDDEN
109 void 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
121 BT_HIDDEN
122 bool 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
133 BT_ASSERT_DBG(ctx->details_comp->meta);
134 details_tc_meta = g_hash_table_lookup(ctx->details_comp->meta, tc);
135 need_to_write = !details_tc_meta;
136
137 end:
138 return need_to_write;
139 }
140
141 BT_HIDDEN
142 int 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
159 static
160 void 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
171 static
172 struct 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
183 end:
184 return details_trace;
185 }
186
187
188 BT_HIDDEN
189 int 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
195 BT_ASSERT_DBG(unique_id);
196 BT_ASSERT_DBG(ctx->details_comp->traces);
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
233 error:
234 ret = -1;
235
236 end:
237 g_free(details_trace);
238
239 return ret;
240 }
This page took 0.036621 seconds and 4 git commands to generate.