2 * Copyright 2019 Philippe Proulx <pproulx@efficios.com>
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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
23 #define BT_LOG_TAG "PLUGIN-TEXT-DETAILS-SINK-OBJ-LIFETIME-MGMT"
26 #include <babeltrace2/babeltrace.h>
28 #include "common/common.h"
29 #include "common/assert.h"
30 #include "compat/glib.h"
34 #include "obj-lifetime-mgmt.h"
37 void trace_class_destruction_listener(const bt_trace_class
*tc
, void *data
)
39 struct details_comp
*details_comp
= data
;
41 BT_ASSERT(details_comp
);
42 BT_ASSERT(details_comp
->meta
);
44 /* Remove from hash table, which also destroys the value */
45 g_hash_table_remove(details_comp
->meta
, tc
);
49 struct details_trace_class_meta
*borrow_trace_class_meta(
50 struct details_write_ctx
*ctx
, const bt_trace_class
*tc
)
52 struct details_trace_class_meta
*details_tc_meta
;
54 BT_ASSERT(ctx
->details_comp
->cfg
.with_meta
);
55 BT_ASSERT(ctx
->details_comp
->meta
);
56 details_tc_meta
= g_hash_table_lookup(ctx
->details_comp
->meta
, tc
);
57 if (!details_tc_meta
) {
58 /* Not found: create one */
59 details_tc_meta
= details_create_details_trace_class_meta();
60 if (!details_tc_meta
) {
64 /* Register trace class destruction listener */
65 if (bt_trace_class_add_destruction_listener(tc
,
66 trace_class_destruction_listener
,
68 &details_tc_meta
->tc_destruction_listener_id
)) {
72 /* Insert into hash table (becomes the owner) */
73 g_hash_table_insert(ctx
->details_comp
->meta
, (void *) tc
,
80 details_destroy_details_trace_class_meta(details_tc_meta
);
81 details_tc_meta
= NULL
;
84 return details_tc_meta
;
88 bool details_need_to_write_meta_object(struct details_write_ctx
*ctx
,
89 const bt_trace_class
*tc
, const void *obj
)
92 struct details_trace_class_meta
*details_tc_meta
;
94 if (!ctx
->details_comp
->cfg
.with_meta
) {
95 need_to_write
= false;
99 BT_ASSERT(ctx
->details_comp
->meta
);
100 details_tc_meta
= g_hash_table_lookup(ctx
->details_comp
->meta
, tc
);
101 BT_ASSERT(details_tc_meta
);
103 g_hash_table_lookup(details_tc_meta
->objects
, obj
) == NULL
;
106 return need_to_write
;
110 void details_did_write_meta_object(struct details_write_ctx
*ctx
,
111 const bt_trace_class
*tc
, const void *obj
)
113 struct details_trace_class_meta
*details_tc_meta
;
115 BT_ASSERT(ctx
->details_comp
->cfg
.with_meta
);
116 details_tc_meta
= borrow_trace_class_meta(ctx
, tc
);
117 BT_ASSERT(details_tc_meta
);
118 g_hash_table_insert(details_tc_meta
->objects
, (gpointer
) obj
,
119 GUINT_TO_POINTER(1));
123 bool details_need_to_write_trace_class(struct details_write_ctx
*ctx
,
124 const bt_trace_class
*tc
)
126 struct details_trace_class_meta
*details_tc_meta
;
129 if (!ctx
->details_comp
->cfg
.with_meta
) {
130 need_to_write
= false;
134 BT_ASSERT(ctx
->details_comp
->meta
);
135 details_tc_meta
= g_hash_table_lookup(ctx
->details_comp
->meta
, tc
);
136 need_to_write
= details_tc_meta
== NULL
;
139 return need_to_write
;
143 int details_did_write_trace_class(struct details_write_ctx
*ctx
,
144 const bt_trace_class
*tc
)
147 struct details_trace_class_meta
*details_tc_meta
;
149 BT_ASSERT(ctx
->details_comp
->cfg
.with_meta
);
151 /* borrow_trace_class_meta() creates an entry if none exists */
152 details_tc_meta
= borrow_trace_class_meta(ctx
, tc
);
153 if (!details_tc_meta
) {
161 void trace_destruction_listener(const bt_trace
*trace
, void *data
)
163 struct details_comp
*details_comp
= data
;
165 BT_ASSERT(details_comp
);
166 BT_ASSERT(details_comp
->traces
);
168 /* Remove from hash table, which also destroys the value */
169 g_hash_table_remove(details_comp
->traces
, trace
);
173 struct details_trace
*create_details_trace(uint64_t unique_id
)
175 struct details_trace
*details_trace
= g_new0(struct details_trace
, 1);
177 if (!details_trace
) {
181 details_trace
->unique_id
= unique_id
;
182 details_trace
->trace_destruction_listener_id
= UINT64_C(-1);
185 return details_trace
;
190 int details_trace_unique_id(struct details_write_ctx
*ctx
,
191 const bt_trace
*trace
, uint64_t *unique_id
)
194 struct details_trace
*details_trace
= NULL
;
196 BT_ASSERT(unique_id
);
197 BT_ASSERT(ctx
->details_comp
->traces
);
198 if (!bt_g_hash_table_contains(ctx
->details_comp
->traces
,
200 /* Not found: create one */
201 *unique_id
= ctx
->details_comp
->next_unique_trace_id
;
202 details_trace
= create_details_trace(*unique_id
);
203 if (!details_trace
) {
207 ctx
->details_comp
->next_unique_trace_id
++;
209 /* Register trace destruction listener if there's none */
210 if (bt_trace_add_destruction_listener(trace
,
211 trace_destruction_listener
,
213 &details_trace
->trace_destruction_listener_id
)) {
217 BT_ASSERT(details_trace
->trace_destruction_listener_id
!=
220 /* Move to hash table */
221 g_hash_table_insert(ctx
->details_comp
->traces
, (gpointer
) trace
,
223 details_trace
= NULL
;
226 details_trace
= g_hash_table_lookup(
227 ctx
->details_comp
->traces
, trace
);
228 *unique_id
= details_trace
->unique_id
;
229 details_trace
= NULL
;
239 g_free(details_trace
);