X-Git-Url: https://git.efficios.com/?a=blobdiff_plain;f=src%2Fcpp-common%2Fbt2%2Fcomponent-class-dev.hpp;h=f97228360d3856e155500ee12013312094b8acf7;hb=ea0030320bb23805e0f7a340930e165e84e8eaf0;hp=1174140f1118b9f21bac3452c86641cab7fc76a9;hpb=212313d92b421f098108a33e0eda7ada08e8a6b8;p=babeltrace.git diff --git a/src/cpp-common/bt2/component-class-dev.hpp b/src/cpp-common/bt2/component-class-dev.hpp index 1174140f..f9722836 100644 --- a/src/cpp-common/bt2/component-class-dev.hpp +++ b/src/cpp-common/bt2/component-class-dev.hpp @@ -16,6 +16,7 @@ #include "cpp-common/vendor/fmt/core.h" #include "exc.hpp" +#include "internal/comp-cls-bridge.hpp" #include "private-query-executor.hpp" #include "self-component-port.hpp" @@ -41,6 +42,9 @@ public: using InitData = InitDataT; using QueryData = QueryDataT; + static constexpr auto description = nullptr; + static constexpr auto help = nullptr; + protected: explicit UserComponent(const SelfCompT selfComp, const std::string& logTag) : _mLogger {selfComp, fmt::format("{}/[{}]", logTag, selfComp.name())}, _mSelfComp {selfComp} @@ -77,6 +81,13 @@ private: /* * Base class of a user source component `UserComponentT` (CRTP). * + * `UserComponentT` must define a static member `name` of type + * `const char *` to provide the name of the component class. + * + * `UserComponentT` may define the static members `description` and/or + * `help` of type `const char *` to provide the description and/or help + * of the component class. + * * UserComponentT::UserComponentT() must accept, in this order: * * 1. A `bt2::SelfSourceComponent` parameter, which it needs to forward @@ -173,6 +184,13 @@ protected: /* * Base class of a user filter component `UserComponentT` (CRTP). * + * `UserComponentT` must define a static member `name` of type + * `const char *` to provide the name of the component class. + * + * `UserComponentT` may define the static members `description` and/or + * `help` of type `const char *` to provide the description and/or help + * of the component class. + * * UserComponentT::UserComponentT() must accept, in this order: * * 1. A `bt2::SelfFilterComponent` parameter, which it needs to forward @@ -297,6 +315,13 @@ protected: /* * Base class of a user sink component `UserComponentT` (CRTP). * + * `UserComponentT` must define a static member `name` of type + * `const char *` to provide the name of the component class. + * + * `UserComponentT` may define the static members `description` and/or + * `help` of type `const char *` to provide the description and/or help + * of the component class. + * * UserComponentT::UserComponentT() must accept, in this order: * * 1. A `bt2::SelfSinkComponent` parameter, which it needs to forward @@ -462,18 +487,13 @@ protected: } public: - ~UserMessageIterator() - { - this->_resetError(); - } - void next(bt2::ConstMessageArray& messages) { /* Any saved error? Now is the time to throw */ if (G_UNLIKELY(_mExcToThrowType != _ExcToThrowType::NONE)) { /* Move `_mSavedLibError`, if any, as current thread error */ if (_mSavedLibError) { - BT_CURRENT_THREAD_MOVE_ERROR_AND_RESET(_mSavedLibError); + bt_current_thread_move_error(_mSavedLibError.release()); } /* Throw the corresponding exception */ @@ -524,7 +544,7 @@ public: "An error occurred, but there are {} messages to return: delaying the error reporting.", messages.length()); BT_ASSERT(!_mSavedLibError); - _mSavedLibError = bt_current_thread_take_error(); + _mSavedLibError.reset(bt_current_thread_take_error()); } } @@ -604,10 +624,7 @@ private: void _resetError() noexcept { _mExcToThrowType = _ExcToThrowType::NONE; - - if (_mSavedLibError) { - bt_error_release(_mSavedLibError); - } + _mSavedLibError.reset(); } SelfMessageIterator _mSelfMsgIter; @@ -621,12 +638,232 @@ private: * It also saves the type of the exception to throw the next time. */ _ExcToThrowType _mExcToThrowType = _ExcToThrowType::NONE; - const bt_error *_mSavedLibError = nullptr; + + struct LibErrorDeleter final + { + void operator()(const bt_error * const error) const noexcept + { + bt_error_release(error); + } + }; + + std::unique_ptr _mSavedLibError; protected: bt2c::Logger _mLogger; }; +namespace internal { + +template +void setCompClsCommonProps( + LibSpecCompClsPtrT * const libSpecCompClsPtr, AsCompClsFuncT&& asCompClsFunc, + SetInitMethodFuncT&& setInitMethodFunc, SetFinalizeMethodFuncT&& setFinalizeMethodFunc, + SetGetSupportedMipVersionsMethodFuncT&& setGetSupportedMipVersionsMethodFunc, + SetQueryMethodFuncT&& setQueryMethodFunc) +{ + const auto libCompClsPtr = asCompClsFunc(libSpecCompClsPtr); + + if (UserComponentT::description != nullptr) { + const auto status = + bt_component_class_set_description(libCompClsPtr, UserComponentT::description); + + if (status == BT_COMPONENT_CLASS_SET_DESCRIPTION_STATUS_MEMORY_ERROR) { + throw MemoryError {}; + } + } + + if (UserComponentT::help != nullptr) { + const auto status = bt_component_class_set_help(libCompClsPtr, UserComponentT::help); + + if (status == BT_COMPONENT_CLASS_SET_HELP_STATUS_MEMORY_ERROR) { + throw MemoryError {}; + } + } + + { + const auto status = setInitMethodFunc(libSpecCompClsPtr, CompClsBridgeT::init); + + BT_ASSERT(status == BT_COMPONENT_CLASS_SET_METHOD_STATUS_OK); + } + + { + const auto status = setFinalizeMethodFunc(libSpecCompClsPtr, CompClsBridgeT::finalize); + + BT_ASSERT(status == BT_COMPONENT_CLASS_SET_METHOD_STATUS_OK); + } + + { + const auto status = setGetSupportedMipVersionsMethodFunc( + libSpecCompClsPtr, CompClsBridgeT::getSupportedMipVersions); + + BT_ASSERT(status == BT_COMPONENT_CLASS_SET_METHOD_STATUS_OK); + } + + { + const auto status = setQueryMethodFunc(libSpecCompClsPtr, CompClsBridgeT::query); + + BT_ASSERT(status == BT_COMPONENT_CLASS_SET_METHOD_STATUS_OK); + } +} + +template +bt_message_iterator_class *createLibMsgIterCls() +{ + const auto libMsgIterClsPtr = bt_message_iterator_class_create(MsgIterClsBridgeT::next); + + if (!libMsgIterClsPtr) { + throw MemoryError {}; + } + + { + const auto status = bt_message_iterator_class_set_initialize_method( + libMsgIterClsPtr, MsgIterClsBridgeT::init); + + BT_ASSERT(status == BT_MESSAGE_ITERATOR_CLASS_SET_METHOD_STATUS_OK); + } + + { + const auto status = bt_message_iterator_class_set_finalize_method( + libMsgIterClsPtr, MsgIterClsBridgeT::finalize); + + BT_ASSERT(status == BT_MESSAGE_ITERATOR_CLASS_SET_METHOD_STATUS_OK); + } + + return libMsgIterClsPtr; +} + +template +bt_component_class_source *createSourceCompCls() +{ + static_assert( + std::is_base_of, + UserComponentT>::value, + "`UserComponentT` inherits `UserSourceComponent`"); + + using CompClsBridge = internal::SrcCompClsBridge; + using MsgIterClsBridge = internal::MsgIterClsBridge; + + const auto libMsgIterClsPtr = createLibMsgIterCls(); + const auto libCompClsPtr = + bt_component_class_source_create(UserComponentT::name, libMsgIterClsPtr); + + bt_message_iterator_class_put_ref(libMsgIterClsPtr); + + if (!libCompClsPtr) { + throw MemoryError {}; + } + + setCompClsCommonProps( + libCompClsPtr, bt_component_class_source_as_component_class, + bt_component_class_source_set_initialize_method, + bt_component_class_source_set_finalize_method, + bt_component_class_source_set_get_supported_mip_versions_method, + bt_component_class_source_set_query_method); + + { + const auto status = bt_component_class_source_set_output_port_connected_method( + libCompClsPtr, CompClsBridge::outputPortConnected); + + BT_ASSERT(status == BT_COMPONENT_CLASS_SET_METHOD_STATUS_OK); + } + + return libCompClsPtr; +} + +template +bt_component_class_filter *createFilterCompCls() +{ + static_assert( + std::is_base_of, + UserComponentT>::value, + "`UserComponentT` inherits `UserFilterComponent`"); + + using CompClsBridge = internal::FltCompClsBridge; + using MsgIterClsBridge = internal::MsgIterClsBridge; + + const auto libMsgIterClsPtr = createLibMsgIterCls(); + const auto libCompClsPtr = + bt_component_class_filter_create(UserComponentT::name, libMsgIterClsPtr); + + bt_message_iterator_class_put_ref(libMsgIterClsPtr); + + if (!libCompClsPtr) { + throw MemoryError {}; + } + + setCompClsCommonProps( + libCompClsPtr, bt_component_class_filter_as_component_class, + bt_component_class_filter_set_initialize_method, + bt_component_class_filter_set_finalize_method, + bt_component_class_filter_set_get_supported_mip_versions_method, + bt_component_class_filter_set_query_method); + + { + const auto status = bt_component_class_filter_set_input_port_connected_method( + libCompClsPtr, CompClsBridge::inputPortConnected); + + BT_ASSERT(status == BT_COMPONENT_CLASS_SET_METHOD_STATUS_OK); + } + + { + const auto status = bt_component_class_filter_set_output_port_connected_method( + libCompClsPtr, CompClsBridge::outputPortConnected); + + BT_ASSERT(status == BT_COMPONENT_CLASS_SET_METHOD_STATUS_OK); + } + + return libCompClsPtr; +} + +template +bt_component_class_sink *createSinkCompCls() +{ + static_assert( + std::is_base_of, + UserComponentT>::value, + "`UserComponentT` inherits `UserSinkComponent`"); + + using CompClsBridge = internal::SinkCompClsBridge; + + const auto libCompClsPtr = + bt_component_class_sink_create(UserComponentT::name, CompClsBridge::consume); + + if (!libCompClsPtr) { + throw MemoryError {}; + } + + setCompClsCommonProps( + libCompClsPtr, bt_component_class_sink_as_component_class, + bt_component_class_sink_set_initialize_method, bt_component_class_sink_set_finalize_method, + bt_component_class_sink_set_get_supported_mip_versions_method, + bt_component_class_sink_set_query_method); + + { + const auto status = bt_component_class_sink_set_graph_is_configured_method( + libCompClsPtr, CompClsBridge::graphIsConfigured); + + BT_ASSERT(status == BT_COMPONENT_CLASS_SET_METHOD_STATUS_OK); + } + + { + const auto status = bt_component_class_sink_set_input_port_connected_method( + libCompClsPtr, CompClsBridge::inputPortConnected); + + BT_ASSERT(status == BT_COMPONENT_CLASS_SET_METHOD_STATUS_OK); + } + + return libCompClsPtr; +} + +} /* namespace internal */ } /* namespace bt2 */ #endif /* BABELTRACE_CPP_COMMON_BT2_COMPONENT_CLASS_DEV_HPP */