31#ifndef DW_FRAMEWORK_PORT_H_
32#define DW_FRAMEWORK_PORT_H_
36#include <dwshared/dwfoundation/dw/core/container/StringView.hpp>
37#include <dwshared/dwfoundation/dw/core/logger/Logger.hpp>
99 static_assert(std::is_copy_constructible<SpecimenT>::value,
"SpecimenT is not copy constructible");
102 static constexpr char LOG_TAG[]{
"PortOutput"};
109 uint32_t m_sendSeqNum;
115 , m_channelProducer(nullptr)
123 , m_channelProducer(nullptr)
124 , m_reference(std::move(ref))
134 , m_channelProducer(
nullptr)
136 , m_waiterAttrs(waiterAttrs)
137 , m_signalerAttrs(signalerAttrs)
156 DW_LOGE << dw::core::StringView{
"PortOutput: bindChannel: attempted to bind the same port twice, ignoring this bind!"} << Logger::State::endl;
159 if (channel ==
nullptr)
161 throw ExceptionWithStatus(DW_INVALID_ARGUMENT,
"PortOutput: bindChannel: expected channel != nullptr");
170 if (m_channelProducer ==
nullptr)
172 throw ExceptionWithStatus(DW_INTERNAL_ERROR,
"PortOutput bindChannel: wrong channel implementations returned.");
175 dw::core::Logger::Verbosity::DEBUG);
182 throw ExceptionWithStatus(DW_NOT_AVAILABLE,
"PortOutput: setOnDataReady: no bound channel");
184 m_channelProducer->
setOnDataReady(opaque, std::move(onDataReady));
189 return (m_channelProducer !=
nullptr);
192 dwStatus
wait(dwTime_t timeout)
196 throw ExceptionWithStatus(DW_NOT_AVAILABLE,
"PortInput: wait: no bound channel");
199 return m_channelProducer->
wait(timeout);
206 dwStatus status{DW_FAILURE};
208 if (m_channelProducer)
210 status = m_channelProducer->
get(&genericData);
213 if (status != DW_SUCCESS)
224 virtual dwStatus
send(T* frame)
226 if (!m_channelProducer)
228 throw ExceptionWithStatus(DW_NOT_AVAILABLE,
"PortOutput: channel not bound");
233 return m_channelProducer->
send(payload);
239 if (!m_channelProducer)
241 throw ExceptionWithStatus(DW_NOT_AVAILABLE,
"PortOutput: channel not bound");
250 if (!m_channelProducer)
252 throw ExceptionWithStatus(DW_NOT_AVAILABLE,
"PortOutput: channel not bound");
264 if (!m_channelProducer)
266 throw ExceptionWithStatus(DW_NOT_AVAILABLE,
"PortOutput: channel not bound");
281 dw::core::safeIncrement(m_sendSeqNum, 1U);
309 "Channel packet type not declared. Ensure channel packet type "
310 "handling is declared with DWFRAMEWORK_DECLARE_PACKET_TYPE_POD "
311 "or DWFRAMEWORK_DECLARE_PACKET_TYPE_RELATION");
313 static constexpr char LOG_TAG[]{
"PortInput"};
322 static_assert(std::is_copy_constructible<SpecimenT>::value,
"SpecimenT is not copy constructible");
327 , m_channelConsumer(nullptr)
335 , m_channelConsumer(nullptr)
337 , m_reference(std::move(ref))
344 , m_channelConsumer(nullptr)
353 , m_channelConsumer(
nullptr)
355 , m_waiterAttrs(waiterAttrs)
356 , m_signalerAttrs(signalerAttrs)
365 , m_channelConsumer(
nullptr)
368 , m_waiterAttrs(waiterAttrs)
369 , m_signalerAttrs(signalerAttrs)
383 DW_LOGE << dw::core::StringView{
"PortInput: bindChannel: attempted to bind the same port twice, ignoring this bind!"} << Logger::State::endl;
386 if (channel ==
nullptr)
388 throw ExceptionWithStatus(DW_INVALID_ARGUMENT,
"PortInput: bindChannel: expected channel != nullptr");
395 if (m_reference.has_value())
397 ref = make_specimen<T>(&m_reference.value());
401 ref.setWaiterAttributes = m_waiterAttrs;
402 ref.setSignalerAttributes = m_signalerAttrs;
405 if (m_channelConsumer ==
nullptr)
407 throw ExceptionWithStatus(DW_INTERNAL_ERROR,
"PortInput bindChannel: wrong channel implementations returned.");
411 dw::core::Logger::Verbosity::DEBUG);
416 return !(m_channelConsumer ==
nullptr);
423 throw ExceptionWithStatus(DW_NOT_AVAILABLE,
"PortInput: setOnDataReady: no bound channel");
425 m_channelConsumer->
setOnDataReady(opaque, std::move(onDataReady));
429 dwStatus
wait(dwTime_t timeout)
433 throw ExceptionWithStatus(DW_NOT_AVAILABLE,
"PortInput: wait: no bound channel");
445 return DW_NOT_AVAILABLE;
453 dwTime_t waitTime{m_last.get() !=
nullptr ? 0 : timeout};
454 dwStatus status{m_channelConsumer->
wait(waitTime)};
455 if (m_last.get() !=
nullptr && (status == DW_TIME_OUT || status == DW_NOT_AVAILABLE))
464 virtual std::shared_ptr<T>
recv()
467 std::shared_ptr<T> result{};
474 T* typedData{
nullptr};
476 void* releasePtr{
nullptr};
482 releasePtr = data.getPointer();
492 dwStatus status{m_channelConsumer->
recv(&data)};
493 if (status != DW_SUCCESS)
495 if (m_last !=
nullptr)
516 releasePtr = data.getPointer();
522 result = std::shared_ptr<T>(typedData, [channelConsumer, releasePtr](T*) {
523 channelConsumer->release(releasePtr);
536 if (!m_channelConsumer)
538 throw ExceptionWithStatus(DW_NOT_AVAILABLE,
"PortInput: channel not bound");
547 if (!m_channelConsumer)
549 throw ExceptionWithStatus(DW_NOT_AVAILABLE,
"PortInput: channel not bound");
561 if (!m_channelConsumer)
563 throw ExceptionWithStatus(DW_NOT_AVAILABLE,
"PortInput: channel not bound");
576 std::shared_ptr<T> m_last;
577 dw::core::Optional<SpecimenT> m_reference;
583constexpr char PortInput<T>::LOG_TAG[];
virtual dwStatus recv(GenericData *data)=0
virtual dwStatus wait(dwTime_t timeout)=0
virtual void setOnDataReady(void *opaque, OnDataReady onDataReady)=0
dw::core::Function< void()> OnDataReady
SyncWaiter & getSyncWaiter()
SyncSignaler & getSyncSignaler()
virtual dwStatus get(GenericData *data)=0
virtual dwStatus send(void *data)=0
virtual void setSignalFences(void *data, dw::core::span< const NvSciSyncFence > postFences)=0
virtual void getWaitFences(void *data, dw::core::span< NvSciSyncFence > &waitFences)=0
virtual const ChannelParams & getParams() const =0
virtual Consumer * getConsumer(const GenericDataReference &ref)=0
virtual Producer * getProducer(const GenericDataReference &ref)=0
bool getReuseEnabled() const
static dwStatus guard(TryBlock const &tryBlock, ::dw::core::Logger::Verbosity verbosity=::dw::core::Logger::Verbosity::ERROR)
virtual ~PortBase()=default
dwStatus wait(dwTime_t timeout)
static constexpr char LOG_TAG[]
dwStatus bindChannelWithReference(ChannelObject *channel, GenericDataReference &ref)
ChannelMetadata & getMetadata(T *frame)
dwStatus bindChannel(ChannelObject *channel) override
void setOnDataReady(void *opaque, ChannelObject::PacketPool::OnDataReady onDataReady)
PortOutput(SpecimenT const &ref)
typename parameter_traits< T >::SpecimenT SpecimenT
ChannelObject::SyncSignaler & getSyncSignaler()
void populateDefaultMetadata(ChannelMetadata &header)
PortOutput(SpecimenT const &ref, OnSetSyncAttrs signalerAttrs, OnSetSyncAttrs waiterAttrs={})
void setSignalFences(T *frame, dw::core::span< NvSciSyncFence > fences)
ChannelObject::SyncWaiter & getSyncWaiter()
void getWaitFences(T *frame, dw::core::span< NvSciSyncFence > fences)
static constexpr PortDirection DIRECTION
PortOutput(SpecimenT &&ref)
virtual dwStatus send(T *frame)
ChannelObject * m_channel
virtual dwStatus bindChannel(ChannelObject *channel)=0
virtual ChannelObject * getChannel()
T * extractInternalPacket(GenericData genericData)
void parseDataSynced(const ChannelParams ¶ms) override
MetadataPayload * getMetadataPacket(T *frame)
MetadataPayload * extractMetadata(GenericData packet)
dw::core::Function< void(NvSciSyncAttrList)> OnSetSyncAttrs
OnSetSyncAttrs setSignalerAttributes
lambda to set the signaler attributes of the endpoint.
ChannelPacketTypeID packetTypeID
The ID of the type of the endpoint.
uint16_t validFields
Bit map defining which ChannelMetadata fields are set. See MetadataFlags.
uint32_t producerId
Id of the producer channel.
uint32_t iterationCount
Producer iteration count.
void setSequenceNumber(ChannelMetadata &header, uint32_t const &sequenceNum)
OnSetSyncAttrs setWaiterAttributes
lambda to set the waiter attributes of the endpoint.
@ METADATA_ITERATION_COUNT
Producer iteration count is set.
ChannelPacketTypeID getNewPacketID(ChannelPacketTypeID packetTypeID)
void stampSyncCount(uint32_t &syncCountOut) const