struct bt_ctf_trace_is_static_listener_elem {
bt_ctf_trace_is_static_listener func;
+ bt_ctf_trace_listener_removed removed;
void *data;
};
BT_LOGD("Destroying trace object: addr=%p, name=\"%s\"",
trace, bt_ctf_trace_get_name(trace));
+ /*
+ * Call remove listeners first so that everything else still
+ * exists in the trace.
+ */
+ if (trace->is_static_listeners) {
+ size_t i;
+
+ for (i = 0; i < trace->is_static_listeners->len; i++) {
+ struct bt_ctf_trace_is_static_listener_elem elem =
+ g_array_index(trace->is_static_listeners,
+ struct bt_ctf_trace_is_static_listener_elem, i);
+
+ if (elem.removed) {
+ elem.removed(trace, elem.data);
+ }
+ }
+
+ g_array_free(trace->is_static_listeners, TRUE);
+ }
+
+ if (trace->listeners) {
+ g_ptr_array_free(trace->listeners, TRUE);
+ }
+
if (trace->environment) {
BT_LOGD_STR("Destroying environment attributes.");
bt_ctf_attributes_destroy(trace->environment);
g_ptr_array_free(trace->stream_classes, TRUE);
}
- if (trace->listeners) {
- g_ptr_array_free(trace->listeners, TRUE);
- }
-
- if (trace->is_static_listeners) {
- g_array_free(trace->is_static_listeners, TRUE);
- }
-
BT_LOGD_STR("Putting packet header field type.");
bt_put(trace->packet_header_type);
g_free(trace);
}
int bt_ctf_trace_add_is_static_listener(struct bt_ctf_trace *trace,
- bt_ctf_trace_is_static_listener listener, void *data)
+ bt_ctf_trace_is_static_listener listener,
+ bt_ctf_trace_listener_removed listener_removed, void *data)
{
int i;
struct bt_ctf_trace_is_static_listener_elem new_elem = {
.func = listener,
+ .removed = listener_removed,
.data = data,
};
goto end;
}
+ if (trace->in_remove_listener) {
+ BT_LOGW("Cannot call this function during the execution of a remove listener: "
+ "addr=%p, name=\"%s\"",
+ trace, bt_ctf_trace_get_name(trace));
+ i = -1;
+ goto end;
+ }
+
/* Find the next available spot */
for (i = 0; i < trace->is_static_listeners->len; i++) {
struct bt_ctf_trace_is_static_listener_elem elem =
goto end;
}
+ if (trace->in_remove_listener) {
+ BT_LOGW("Cannot call this function during the execution of a remove listener: "
+ "addr=%p, name=\"%s\", listener-id=%d",
+ trace, bt_ctf_trace_get_name(trace),
+ listener_id);
+ ret = -1;
+ goto end;
+ }
+
if (listener_id < 0) {
BT_LOGW("Invalid listener ID: must be zero or positive: "
"listener-id=%d", listener_id);
goto end;
}
+ if (elem->removed) {
+ /* Call remove listener */
+ BT_LOGV("Calling remove listener: "
+ "trace-addr=%p, trace-name=\"%s\", "
+ "listener-id=%d", trace, bt_ctf_trace_get_name(trace),
+ listener_id);
+ trace->in_remove_listener = BT_TRUE;
+ elem->removed(trace, elem->data);
+ trace->in_remove_listener = BT_FALSE;
+ }
+
elem->func = NULL;
+ elem->removed = NULL;
elem->data = NULL;
BT_LOGV("Removed \"trace is static\" listener: "
"trace-addr=%p, trace-name=\"%s\", "