#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"
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}
{
}
-protected:
bt2c::CStringView _name() const noexcept
{
return _mSelfComp.name();
/*
* 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
}
static void getSupportedMipVersions(const SelfComponentClass selfCompCls,
- const ConstValue params, const LoggingLevel loggingLevel,
+ const ConstMapValue params, const LoggingLevel loggingLevel,
const UnsignedIntegerRangeSet ranges)
{
UserComponentT::_getSupportedMipVersions(selfCompCls, params, loggingLevel, ranges);
}
/* Overloadable */
- static void _getSupportedMipVersions(SelfComponentClass, ConstValue, LoggingLevel,
+ static void _getSupportedMipVersions(SelfComponentClass, ConstMapValue, LoggingLevel,
const UnsignedIntegerRangeSet ranges)
{
ranges.addRange(0, 0);
/*
* 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
}
static void getSupportedMipVersions(const SelfComponentClass selfCompCls,
- const ConstValue params, const LoggingLevel loggingLevel,
+ const ConstMapValue params, const LoggingLevel loggingLevel,
const UnsignedIntegerRangeSet ranges)
{
UserComponentT::_getSupportedMipVersions(selfCompCls, params, loggingLevel, ranges);
}
/* Overloadable */
- static void _getSupportedMipVersions(SelfComponentClass, ConstValue, LoggingLevel,
+ static void _getSupportedMipVersions(SelfComponentClass, ConstMapValue, LoggingLevel,
const UnsignedIntegerRangeSet ranges)
{
ranges.addRange(0, 0);
/*
* 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
}
static void getSupportedMipVersions(const SelfComponentClass selfCompCls,
- const ConstValue params, const LoggingLevel loggingLevel,
+ const ConstMapValue params, const LoggingLevel loggingLevel,
const UnsignedIntegerRangeSet ranges)
{
UserComponentT::_getSupportedMipVersions(selfCompCls, params, loggingLevel, ranges);
}
/* Overloadable */
- static void _getSupportedMipVersions(SelfComponentClass, ConstValue, LoggingLevel,
+ static void _getSupportedMipVersions(SelfComponentClass, ConstMapValue, LoggingLevel,
const UnsignedIntegerRangeSet ranges)
{
ranges.addRange(0, 0);
/* Type of `_mExcToThrowType` */
enum class _ExcToThrowType
{
- NONE,
- ERROR,
- MEM_ERROR,
+ None,
+ Error,
+ MemError,
};
protected:
}
public:
- ~UserMessageIterator()
- {
- this->_resetError();
- }
-
- void next(bt2::ConstMessageArray& messages)
+ void next(ConstMessageArray& messages)
{
/* Any saved error? Now is the time to throw */
- if (G_UNLIKELY(_mExcToThrowType != _ExcToThrowType::NONE)) {
+ 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 */
- if (_mExcToThrowType == _ExcToThrowType::ERROR) {
- throw bt2::Error {};
+ if (_mExcToThrowType == _ExcToThrowType::Error) {
+ throw Error {};
} else {
- BT_ASSERT(_mExcToThrowType == _ExcToThrowType::MEM_ERROR);
- throw bt2::MemoryError {};
+ BT_ASSERT(_mExcToThrowType == _ExcToThrowType::MemError);
+ throw MemoryError {};
}
}
* if any, so that we can restore it later (see the beginning of
* this method).
*/
- BT_ASSERT_DBG(_mExcToThrowType == _ExcToThrowType::NONE);
+ BT_ASSERT_DBG(_mExcToThrowType == _ExcToThrowType::None);
try {
this->_userObj()._next(messages);
/* We're done: everything below is exception handling */
return;
- } catch (const bt2::TryAgain&) {
+ } catch (const TryAgain&) {
if (messages.isEmpty()) {
throw;
}
throw;
}
- _mExcToThrowType = _ExcToThrowType::MEM_ERROR;
- } catch (const bt2::Error&) {
+ _mExcToThrowType = _ExcToThrowType::MemError;
+ } catch (const Error&) {
if (messages.isEmpty()) {
throw;
}
- _mExcToThrowType = _ExcToThrowType::ERROR;
+ _mExcToThrowType = _ExcToThrowType::Error;
}
- if (_mExcToThrowType != _ExcToThrowType::NONE) {
+ if (_mExcToThrowType != _ExcToThrowType::None) {
BT_CPPLOGE(
"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());
}
}
return _mSelfMsgIter.createMessageIterator(port);
}
+ StreamBeginningMessage::Shared _createStreamBeginningMessage(const ConstStream stream) const
+ {
+ return _mSelfMsgIter.createStreamBeginningMessage(stream);
+ }
+
+ StreamEndMessage::Shared _createStreamEndMessage(const ConstStream stream) const
+ {
+ return _mSelfMsgIter.createStreamEndMessage(stream);
+ }
+
+ EventMessage::Shared _createEventMessage(const ConstEventClass eventCls,
+ const ConstStream stream) const
+ {
+ return _mSelfMsgIter.createEventMessage(eventCls, stream);
+ }
+
+ EventMessage::Shared _createEventMessage(const ConstEventClass eventCls,
+ const ConstStream stream,
+ const std::uint64_t clockSnapshotValue) const
+ {
+ return _mSelfMsgIter.createEventMessage(eventCls, stream, clockSnapshotValue);
+ }
+
+ EventMessage::Shared _createEventMessage(const ConstEventClass eventCls,
+ const ConstPacket packet) const
+ {
+ return _mSelfMsgIter.createEventMessage(eventCls, packet);
+ }
+
+ EventMessage::Shared _createEventMessage(const ConstEventClass eventCls,
+ const ConstPacket packet,
+ const std::uint64_t clockSnapshotValue) const
+ {
+ return _mSelfMsgIter.createEventMessage(eventCls, packet, clockSnapshotValue);
+ }
+
+ PacketBeginningMessage::Shared _createPacketBeginningMessage(const ConstPacket packet) const
+ {
+ return _mSelfMsgIter.createPacketBeginningMessage(packet);
+ }
+
+ PacketBeginningMessage::Shared
+ _createPacketBeginningMessage(const ConstPacket packet,
+ const std::uint64_t clockSnapshotValue) const
+ {
+ return _mSelfMsgIter.createPacketBeginningMessage(packet, clockSnapshotValue);
+ }
+
+ PacketEndMessage::Shared _createPacketEndMessage(const ConstPacket packet) const
+ {
+ return _mSelfMsgIter.createPacketEndMessage(packet);
+ }
+
+ PacketEndMessage::Shared _createPacketEndMessage(const ConstPacket packet,
+ const std::uint64_t clockSnapshotValue) const
+ {
+ return _mSelfMsgIter.createPacketEndMessage(packet, clockSnapshotValue);
+ }
+
+ DiscardedEventsMessage::Shared _createDiscardedEventsMessage(const ConstStream stream)
+ {
+ return _mSelfMsgIter.createDiscardedEventsMessage(stream);
+ }
+
+ DiscardedEventsMessage::Shared
+ _createDiscardedEventsMessage(const ConstStream stream,
+ const std::uint64_t beginningClockSnapshotValue,
+ const std::uint64_t endClockSnapshotValue)
+ {
+ return _mSelfMsgIter.createDiscardedEventsMessage(stream, beginningClockSnapshotValue,
+ endClockSnapshotValue);
+ }
+
+ DiscardedPacketsMessage::Shared _createDiscardedPacketsMessage(const ConstStream stream)
+ {
+ return _mSelfMsgIter.createDiscardedPacketsMessage(stream);
+ }
+
+ DiscardedPacketsMessage::Shared
+ _createDiscardedPacketsMessage(const ConstStream stream,
+ const std::uint64_t beginningClockSnapshotValue,
+ const std::uint64_t endClockSnapshotValue)
+ {
+ return _mSelfMsgIter.createDiscardedPacketsMessage(stream, beginningClockSnapshotValue,
+ endClockSnapshotValue);
+ }
+
+ MessageIteratorInactivityMessage::Shared
+ _createMessageIteratorInactivityMessage(const ConstClockClass clockClass,
+ const std::uint64_t clockSnapshotValue)
+ {
+ return _mSelfMsgIter.createMessageIteratorInactivityMessage(clockClass, clockSnapshotValue);
+ }
+
UserComponentT& _component() noexcept
{
return _mSelfMsgIter.component().template data<UserComponentT>();
void _resetError() noexcept
{
- _mExcToThrowType = _ExcToThrowType::NONE;
-
- if (_mSavedLibError) {
- bt_error_release(_mSavedLibError);
- }
+ _mExcToThrowType = _ExcToThrowType::None;
+ _mSavedLibError.reset();
}
SelfMessageIterator _mSelfMsgIter;
*
* It also saves the type of the exception to throw the next time.
*/
- _ExcToThrowType _mExcToThrowType = _ExcToThrowType::NONE;
- const bt_error *_mSavedLibError = nullptr;
+ _ExcToThrowType _mExcToThrowType = _ExcToThrowType::None;
+
+ struct LibErrorDeleter final
+ {
+ void operator()(const bt_error * const error) const noexcept
+ {
+ bt_error_release(error);
+ }
+ };
+
+ std::unique_ptr<const bt_error, LibErrorDeleter> _mSavedLibError;
protected:
bt2c::Logger _mLogger;
};
+namespace internal {
+
+template <typename UserComponentT, typename CompClsBridgeT, typename LibSpecCompClsPtrT,
+ typename AsCompClsFuncT, typename SetInitMethodFuncT, typename SetFinalizeMethodFuncT,
+ typename SetGetSupportedMipVersionsMethodFuncT, typename SetQueryMethodFuncT>
+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 <typename MsgIterClsBridgeT>
+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 <typename UserComponentT>
+bt_component_class_source *createSourceCompCls()
+{
+ static_assert(
+ std::is_base_of<UserSourceComponent<
+ UserComponentT, typename UserComponentT::MessageIterator,
+ typename UserComponentT::InitData, typename UserComponentT::QueryData>,
+ UserComponentT>::value,
+ "`UserComponentT` inherits `UserSourceComponent`");
+
+ using CompClsBridge = internal::SrcCompClsBridge<UserComponentT>;
+ using MsgIterClsBridge = internal::MsgIterClsBridge<typename UserComponentT::MessageIterator>;
+
+ const auto libMsgIterClsPtr = createLibMsgIterCls<MsgIterClsBridge>();
+ const auto libCompClsPtr =
+ bt_component_class_source_create(UserComponentT::name, libMsgIterClsPtr);
+
+ bt_message_iterator_class_put_ref(libMsgIterClsPtr);
+
+ if (!libCompClsPtr) {
+ throw MemoryError {};
+ }
+
+ setCompClsCommonProps<UserComponentT, CompClsBridge>(
+ 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 <typename UserComponentT>
+bt_component_class_filter *createFilterCompCls()
+{
+ static_assert(
+ std::is_base_of<UserFilterComponent<
+ UserComponentT, typename UserComponentT::MessageIterator,
+ typename UserComponentT::InitData, typename UserComponentT::QueryData>,
+ UserComponentT>::value,
+ "`UserComponentT` inherits `UserFilterComponent`");
+
+ using CompClsBridge = internal::FltCompClsBridge<UserComponentT>;
+ using MsgIterClsBridge = internal::MsgIterClsBridge<typename UserComponentT::MessageIterator>;
+
+ const auto libMsgIterClsPtr = createLibMsgIterCls<MsgIterClsBridge>();
+ const auto libCompClsPtr =
+ bt_component_class_filter_create(UserComponentT::name, libMsgIterClsPtr);
+
+ bt_message_iterator_class_put_ref(libMsgIterClsPtr);
+
+ if (!libCompClsPtr) {
+ throw MemoryError {};
+ }
+
+ setCompClsCommonProps<UserComponentT, CompClsBridge>(
+ 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 <typename UserComponentT>
+bt_component_class_sink *createSinkCompCls()
+{
+ static_assert(
+ std::is_base_of<UserSinkComponent<UserComponentT, typename UserComponentT::InitData,
+ typename UserComponentT::QueryData>,
+ UserComponentT>::value,
+ "`UserComponentT` inherits `UserSinkComponent`");
+
+ using CompClsBridge = internal::SinkCompClsBridge<UserComponentT>;
+
+ const auto libCompClsPtr =
+ bt_component_class_sink_create(UserComponentT::name, CompClsBridge::consume);
+
+ if (!libCompClsPtr) {
+ throw MemoryError {};
+ }
+
+ setCompClsCommonProps<UserComponentT, CompClsBridge>(
+ 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 */