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>
56T* getBufferTyped(GenericData buffer)
59 T* ptr{metadataPacket->
data.template getData<T>()};
63 throw ExceptionWithStatus(DW_INVALID_ARGUMENT,
"getBufferTyped: type mismatch");
72 explicit vectorIterable(dw::core::VectorFixed<GenericData> allBuffers)
73 : m_allBuffers(std::move(allBuffers))
81 class iterator :
public dw::core::VectorFixed<GenericData>::iterator
84 using Base = dw::core::VectorFixed<GenericData>::iterator;
88 : Base(std::move(base))
92 const Base& baseFromThis()
const
99 GenericData buffer{*baseFromThis()};
100 return getBufferTyped<TT>(buffer);
105 iterator<T> begin() {
return iterator<T>(m_allBuffers.begin()); }
108 iterator<T> end() {
return iterator<T>(m_allBuffers.end()); }
111 iterator<const T> begin()
const {
return iterator<const T>(m_allBuffers.begin()); }
114 iterator<const T> end()
const {
return iterator<const T>(m_allBuffers.end()); }
117 dw::core::VectorFixed<GenericData> m_allBuffers;
170 static_assert(std::is_copy_constructible<SpecimenT>::value,
"SpecimenT is not copy constructible");
173 static constexpr char LOG_TAG[]{
"PortOutput"};
180 uint32_t m_sendSeqNum;
186 , m_channelProducer(nullptr)
194 , m_channelProducer(nullptr)
195 , m_reference(std::move(ref))
205 , m_channelProducer(
nullptr)
207 , m_waiterAttrs(waiterAttrs)
208 , m_signalerAttrs(signalerAttrs)
227 DW_LOGE << dw::core::StringView{
"PortOutput: bindChannel: attempted to bind the same port twice, ignoring this bind!"} << Logger::State::endl;
230 if (
nullptr == channel)
232 throw ExceptionWithStatus(DW_INVALID_ARGUMENT,
"PortOutput: bindChannel: expected channel != nullptr");
241 if (
nullptr == m_channelProducer)
243 throw ExceptionWithStatus(DW_INTERNAL_ERROR,
"PortOutput bindChannel: wrong channel implementations returned.");
246 dw::core::Logger::Verbosity::DEBUG);
261 DW_LOGE << dw::core::StringView{
"PortOutput: bindChannelForPODTypePacket: attempted to bind the same port twice, ignoring this bind!"} << Logger::State::endl;
264 if (
nullptr == channel)
266 throw ExceptionWithStatus(DW_INVALID_ARGUMENT,
"PortOutput: bindChannelForPODTypePacket: expected channel != nullptr");
270 throw dw::core::ExceptionWithStatus(DW_CALL_NOT_ALLOWED,
"PortOutput: bindChannelForPODTypePacket: setting channel to use POD type only allowed for local channels.");
277 ref.typeSize =
sizeof(T);
279 ref.setWaiterAttributes = m_waiterAttrs;
280 ref.setSignalerAttributes = m_signalerAttrs;
283 if (
nullptr == m_channelProducer)
285 throw ExceptionWithStatus(DW_INTERNAL_ERROR,
"PortOutput bindChannelForPODTypePacket: wrong channel implementations returned.");
288 dw::core::Logger::Verbosity::DEBUG);
295 throw ExceptionWithStatus(DW_NOT_AVAILABLE,
"PortOutput: setOnDataReady: no bound channel");
297 m_channelProducer->
setOnDataReady(opaque, std::move(onDataReady));
302 return (
nullptr != m_channelProducer);
305 dwStatus
wait(dwTime_t timeout)
309 throw ExceptionWithStatus(DW_NOT_AVAILABLE,
"PortOutput: wait: no bound channel");
312 return m_channelProducer->
wait(timeout);
319 dwStatus status{DW_FAILURE};
321 if (m_channelProducer)
323 status = m_channelProducer->
get(&genericData);
326 if (DW_SUCCESS != status)
337 virtual dwStatus
send(T* frame)
339 if (!m_channelProducer)
341 throw ExceptionWithStatus(DW_NOT_AVAILABLE,
"PortOutput: channel not bound");
346 return m_channelProducer->
send(payload);
352 if (!m_channelProducer)
354 throw ExceptionWithStatus(DW_NOT_AVAILABLE,
"PortOutput: channel not bound");
363 if (!m_channelProducer)
365 throw ExceptionWithStatus(DW_NOT_AVAILABLE,
"PortOutput: channel not bound");
377 if (!m_channelProducer)
379 throw ExceptionWithStatus(DW_NOT_AVAILABLE,
"PortOutput: channel not bound");
394 return detail::vectorIterable<T>(m_channelProducer->
getAllBuffers());
401 if (m_sendSeqNum < std::numeric_limits<
decltype(m_sendSeqNum)>::max())
407 m_sendSeqNum = std::numeric_limits<
decltype(m_sendSeqNum)>::min();
436 "Channel packet type not declared. Ensure channel packet type "
437 "handling is declared with DWFRAMEWORK_DECLARE_PACKET_TYPE_POD "
438 "or DWFRAMEWORK_DECLARE_PACKET_TYPE_RELATION");
440 static constexpr char LOG_TAG[]{
"PortInput"};
449 static_assert(std::is_copy_constructible<SpecimenT>::value,
"SpecimenT is not copy constructible");
454 , m_channelConsumer(nullptr)
462 , m_channelConsumer(nullptr)
464 , m_reference(std::move(ref))
471 , m_channelConsumer(nullptr)
480 , m_channelConsumer(
nullptr)
482 , m_waiterAttrs(waiterAttrs)
483 , m_signalerAttrs(signalerAttrs)
492 , m_channelConsumer(
nullptr)
495 , m_waiterAttrs(waiterAttrs)
496 , m_signalerAttrs(signalerAttrs)
510 DW_LOGE << dw::core::StringView{
"PortInput: bindChannel: attempted to bind the same port twice, ignoring this bind!"} << Logger::State::endl;
513 if (
nullptr == channel)
515 throw ExceptionWithStatus(DW_INVALID_ARGUMENT,
"PortInput: bindChannel: expected channel != nullptr");
522 if (m_reference.has_value())
524 ref = make_specimen<T>(&m_reference.value());
528 ref.setWaiterAttributes = m_waiterAttrs;
529 ref.setSignalerAttributes = m_signalerAttrs;
532 if (
nullptr == m_channelConsumer)
534 throw ExceptionWithStatus(DW_INTERNAL_ERROR,
"PortInput bindChannel: wrong channel implementations returned.");
538 dw::core::Logger::Verbosity::DEBUG);
543 return !(
nullptr == m_channelConsumer);
550 throw ExceptionWithStatus(DW_NOT_AVAILABLE,
"PortInput: setOnDataReady: no bound channel");
552 m_channelConsumer->
setOnDataReady(opaque, std::move(onDataReady));
556 dwStatus
wait(dwTime_t timeout)
560 throw ExceptionWithStatus(DW_NOT_AVAILABLE,
"PortInput: wait: no bound channel");
572 return DW_NOT_AVAILABLE;
580 dwTime_t waitTime{
nullptr != m_last.get() ? 0 : timeout};
581 dwStatus status{m_channelConsumer->
wait(waitTime)};
582 if (
nullptr != m_last.get() && (DW_TIME_OUT == status || DW_NOT_AVAILABLE == status))
591 virtual std::shared_ptr<T>
recv()
594 std::shared_ptr<T> result{};
601 T* typedData{
nullptr};
603 void* releasePtr{
nullptr};
609 releasePtr = data.getPointer();
619 dwStatus status{m_channelConsumer->
recv(&data)};
620 if (DW_SUCCESS != status)
622 if (
nullptr != m_last)
643 releasePtr = data.getPointer();
649 result = std::shared_ptr<T>(typedData, [channelConsumer, releasePtr](T*) {
650 channelConsumer->release(releasePtr);
663 if (!m_channelConsumer)
665 throw ExceptionWithStatus(DW_NOT_AVAILABLE,
"PortInput: channel not bound");
674 if (!m_channelConsumer)
676 throw ExceptionWithStatus(DW_NOT_AVAILABLE,
"PortInput: channel not bound");
688 if (!m_channelConsumer)
690 throw ExceptionWithStatus(DW_NOT_AVAILABLE,
"PortInput: channel not bound");
705 return detail::vectorIterable<T>(m_channelConsumer->
getAllBuffers());
711 std::shared_ptr<T> m_last;
712 dw::core::Optional<SpecimenT> m_reference;
718constexpr 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()
virtual dw::core::VectorFixed< GenericData > getAllBuffers()=0
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
ChannelType getType() const
static dwStatus guard(TryBlock const &tryBlock, ::dw::core::Logger::Verbosity verbosity=::dw::core::Logger::Verbosity::ERROR)
virtual ~PortBase()=default
detail::vectorIterable< T > getAllBufferIter()
dwStatus wait(dwTime_t timeout)
static constexpr char LOG_TAG[]
dwStatus bindChannelWithReference(ChannelObject *channel, GenericDataReference &ref)
ChannelMetadata & getMetadata(T *frame)
dwStatus bindChannelForPODTypePacket(ChannelObject *channel)
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)
static constexpr const uint32_t DWFRAMEWORK_METADATA_PACKET_TYPE_ID_OFFSET
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 ChannelPacketTypeID
constexpr ChannelPacketTypeID DWFRAMEWORK_PACKET_ID_DEFAULT
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.
@ SHMEM_LOCAL
local shared memory
ChannelPacketTypeID getNewPacketID(ChannelPacketTypeID packetTypeID)
void stampSyncCount(uint32_t &syncCountOut) const