X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;ds=sidebyside;f=src%2Flib%2Ftrace-ir%2Ftrace-class.c;h=90ae4de74f7ca6dd2416785b131dc56165ac0058;hb=0235b0db7de5bcacdb3650c92461f2ce5eb2143d;hp=9ad5849f78c5a0f7e93d89107eec8de5ab3e45c4;hpb=335a2da576e59d32c17de2ece1e7e339c50e9c25;p=babeltrace.git diff --git a/src/lib/trace-ir/trace-class.c b/src/lib/trace-ir/trace-class.c index 9ad5849f..90ae4de7 100644 --- a/src/lib/trace-ir/trace-class.c +++ b/src/lib/trace-ir/trace-class.c @@ -1,38 +1,21 @@ /* + * SPDX-License-Identifier: MIT + * * Copyright 2017-2018 Philippe Proulx * Copyright 2014 Jérémie Galarneau - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. */ -#define BT_LOG_TAG "LIB/TRACE" +#define BT_LOG_TAG "LIB/TRACE-CLASS" #include "lib/logging.h" #include "lib/assert-pre.h" +#include "lib/assert-post.h" #include -#include #include #include "ctf-writer/functor.h" #include "ctf-writer/clock.h" #include "compat/compiler.h" #include -#include #include "lib/value.h" #include #include "compat/endian.h" @@ -41,6 +24,7 @@ #include #include #include +#include #include #include "clock-class.h" @@ -53,6 +37,7 @@ #include "stream.h" #include "trace.h" #include "utils.h" +#include "lib/value.h" #include "lib/func-status.h" struct bt_trace_class_destruction_listener_elem { @@ -60,8 +45,8 @@ struct bt_trace_class_destruction_listener_elem { void *data; }; -#define BT_ASSERT_PRE_TRACE_CLASS_HOT(_tc) \ - BT_ASSERT_PRE_HOT((_tc), "Trace class", ": %!+T", (_tc)) +#define BT_ASSERT_PRE_DEV_TRACE_CLASS_HOT(_tc) \ + BT_ASSERT_PRE_DEV_HOT((_tc), "Trace class", ": %!+T", (_tc)) static void destroy_trace_class(struct bt_object *obj) @@ -69,12 +54,16 @@ void destroy_trace_class(struct bt_object *obj) struct bt_trace_class *tc = (void *) obj; BT_LIB_LOGD("Destroying trace class object: %!+T", tc); + BT_OBJECT_PUT_REF_AND_RESET(tc->user_attributes); + /* * Call destruction listener functions so that everything else * still exists in the trace class. */ if (tc->destruction_listeners) { uint64_t i; + const struct bt_error *saved_error; + BT_LIB_LOGD("Calling trace class destruction listener(s): %!+T", tc); /* @@ -89,6 +78,8 @@ void destroy_trace_class(struct bt_object *obj) */ tc->base.ref_count++; + saved_error = bt_current_thread_take_error(); + /* Call all the trace class destruction listeners */ for (i = 0; i < tc->destruction_listeners->len; i++) { struct bt_trace_class_destruction_listener_elem elem = @@ -97,16 +88,21 @@ void destroy_trace_class(struct bt_object *obj) if (elem.func) { elem.func(tc, elem.data); + BT_ASSERT_POST_NO_ERROR(); } /* * The destruction listener should not have kept a * reference to the trace class. */ - BT_ASSERT_PRE(tc->base.ref_count == 1, "Destruction listener kept a reference to the trace class being destroyed: %![tc-]+T", tc); + BT_ASSERT_POST(tc->base.ref_count == 1, "Destruction listener kept a reference to the trace class being destroyed: %![tc-]+T", tc); } g_array_free(tc->destruction_listeners, TRUE); tc->destruction_listeners = NULL; + + if (saved_error) { + BT_CURRENT_THREAD_MOVE_ERROR_AND_RESET(saved_error); + } } if (tc->stream_classes) { @@ -122,6 +118,7 @@ struct bt_trace_class *bt_trace_class_create(bt_self_component *self_comp) { struct bt_trace_class *tc = NULL; + BT_ASSERT_PRE_NO_ERROR(); BT_ASSERT_PRE_NON_NULL(self_comp, "Self component"); BT_LOGD_STR("Creating default trace class object."); tc = g_new0(struct bt_trace_class, 1); @@ -131,6 +128,12 @@ struct bt_trace_class *bt_trace_class_create(bt_self_component *self_comp) } bt_object_init_shared_with_parent(&tc->base, destroy_trace_class); + tc->user_attributes = bt_value_map_create(); + if (!tc->user_attributes) { + BT_LIB_LOGE_APPEND_CAUSE( + "Failed to create a map value object."); + goto error; + } tc->stream_classes = g_ptr_array_new_with_free_func( (GDestroyNotify) bt_object_try_spec_release); @@ -160,7 +163,7 @@ end: enum bt_trace_class_add_listener_status bt_trace_class_add_destruction_listener( const struct bt_trace_class *_tc, bt_trace_class_destruction_listener_func listener, - void *data, uint64_t *listener_id) + void *data, bt_listener_id *listener_id) { struct bt_trace_class *tc = (void *) _tc; uint64_t i; @@ -169,6 +172,7 @@ enum bt_trace_class_add_listener_status bt_trace_class_add_destruction_listener( .data = data, }; + BT_ASSERT_PRE_NO_ERROR(); BT_ASSERT_PRE_NON_NULL(tc, "Trace class"); BT_ASSERT_PRE_NON_NULL(listener, "Listener"); @@ -198,22 +202,22 @@ enum bt_trace_class_add_listener_status bt_trace_class_add_destruction_listener( return BT_FUNC_STATUS_OK; } -BT_ASSERT_PRE_FUNC static bool has_listener_id(const struct bt_trace_class *tc, uint64_t listener_id) { BT_ASSERT(listener_id < tc->destruction_listeners->len); return (&g_array_index(tc->destruction_listeners, struct bt_trace_class_destruction_listener_elem, - listener_id))->func != NULL; + listener_id))->func; } enum bt_trace_class_remove_listener_status bt_trace_class_remove_destruction_listener( - const struct bt_trace_class *_tc, uint64_t listener_id) + const struct bt_trace_class *_tc, bt_listener_id listener_id) { struct bt_trace_class *tc = (void *) _tc; struct bt_trace_class_destruction_listener_elem *elem; + BT_ASSERT_PRE_NO_ERROR(); BT_ASSERT_PRE_NON_NULL(tc, "Trace class"); BT_ASSERT_PRE(has_listener_id(tc, listener_id), "Trace class has no such trace class destruction listener ID: " @@ -233,15 +237,15 @@ enum bt_trace_class_remove_listener_status bt_trace_class_remove_destruction_lis uint64_t bt_trace_class_get_stream_class_count(const struct bt_trace_class *tc) { - BT_ASSERT_PRE_NON_NULL(tc, "Trace class"); + BT_ASSERT_PRE_DEV_NON_NULL(tc, "Trace class"); return (uint64_t) tc->stream_classes->len; } struct bt_stream_class *bt_trace_class_borrow_stream_class_by_index( struct bt_trace_class *tc, uint64_t index) { - BT_ASSERT_PRE_NON_NULL(tc, "Trace class"); - BT_ASSERT_PRE_VALID_INDEX(index, tc->stream_classes->len); + BT_ASSERT_PRE_DEV_NON_NULL(tc, "Trace class"); + BT_ASSERT_PRE_DEV_VALID_INDEX(index, tc->stream_classes->len); return g_ptr_array_index(tc->stream_classes, index); } @@ -259,7 +263,7 @@ struct bt_stream_class *bt_trace_class_borrow_stream_class_by_id( struct bt_stream_class *stream_class = NULL; uint64_t i; - BT_ASSERT_PRE_NON_NULL(tc, "Trace class"); + BT_ASSERT_PRE_DEV_NON_NULL(tc, "Trace class"); for (i = 0; i < tc->stream_classes->len; i++) { struct bt_stream_class *stream_class_candidate = @@ -292,7 +296,7 @@ void _bt_trace_class_freeze(const struct bt_trace_class *tc) bt_bool bt_trace_class_assigns_automatic_stream_class_id(const struct bt_trace_class *tc) { - BT_ASSERT_PRE_NON_NULL(tc, "Trace class"); + BT_ASSERT_PRE_DEV_NON_NULL(tc, "Trace class"); return (bt_bool) tc->assigns_automatic_stream_class_id; } @@ -300,12 +304,39 @@ void bt_trace_class_set_assigns_automatic_stream_class_id(struct bt_trace_class bt_bool value) { BT_ASSERT_PRE_NON_NULL(tc, "Trace class"); - BT_ASSERT_PRE_TRACE_CLASS_HOT(tc); + BT_ASSERT_PRE_DEV_TRACE_CLASS_HOT(tc); tc->assigns_automatic_stream_class_id = (bool) value; BT_LIB_LOGD("Set trace class's automatic stream class ID " "assignment property: %!+T", tc); } +const struct bt_value *bt_trace_class_borrow_user_attributes_const( + const struct bt_trace_class *trace_class) +{ + BT_ASSERT_PRE_DEV_NON_NULL(trace_class, "Trace class"); + return trace_class->user_attributes; +} + +struct bt_value *bt_trace_class_borrow_user_attributes( + struct bt_trace_class *trace_class) +{ + return (void *) bt_trace_class_borrow_user_attributes_const( + (void *) trace_class); +} + +void bt_trace_class_set_user_attributes(struct bt_trace_class *trace_class, + const struct bt_value *user_attributes) +{ + BT_ASSERT_PRE_NON_NULL(trace_class, "Trace class"); + BT_ASSERT_PRE_NON_NULL(user_attributes, "User attributes"); + BT_ASSERT_PRE(user_attributes->type == BT_VALUE_TYPE_MAP, + "User attributes object is not a map value object."); + BT_ASSERT_PRE_DEV_TRACE_CLASS_HOT(trace_class); + bt_object_put_ref_no_null_check(trace_class->user_attributes); + trace_class->user_attributes = (void *) user_attributes; + bt_object_get_ref_no_null_check(trace_class->user_attributes); +} + void bt_trace_class_get_ref(const struct bt_trace_class *trace_class) { bt_object_get_ref(trace_class);