#ifndef TCPS_FRAME_QUEUE_H_ #define TCPS_FRAME_QUEUE_H_ /** * @file TCPSFrameQueue.h * @brief Bounded per-connection output queue of UDPS frames (header + payload). * * Same semantics as the per-client queue inside TCPSServer: at most `depth` * DATA frames wait; when full the oldest DATA frame that is not already * (partially) on the wire is discarded and counted. A CONFIG is never dropped * and, when queued, discards the DATA frames behind the one on the wire (they * were encoded for the previous layout). * * Not thread-safe: the owner serialises Push() / Flush(). */ #include "CompilerTypes.h" namespace MARTe { class TCPSFrameQueue { public: TCPSFrameQueue(); ~TCPSFrameQueue(); /** Allocate `depth` DATA slots plus two CONFIG slots (room for one stream). */ void Init(uint32 depth); /** * Make room for @p numStreams multiplexed streams: each gets its own `depth` * DATA frames plus two CONFIG slots. Grow-only; call while the queue is idle * (before the connection is attached to any stream). */ void Reserve(uint32 numStreams); /** * Append a complete frame (copied). The frame is stamped with @p streamIdx in * its header's fragmentIdx field. Accounting is per stream: a full stream * evicts its own oldest DATA, and a CONFIG only discards the queued frames * of its own stream. * @param[in,out] dropped incremented by the number of DATA frames discarded. * @return false if the frame itself was refused (queue full of in-flight data). */ bool Push(uint16 streamIdx, bool isConfig, const uint8 *frame, uint32 frameBytes, uint32 &dropped); /** * Write as much as the socket accepts without blocking, batching up to * TCPS_MAX_BATCH frames per system call. * @return false if the connection is broken. */ bool Flush(int fd); /** Most frames sent by one sendmsg(). */ static const uint32 TCPS_MAX_BATCH = 16u; bool Empty() const; /** HRT ticks of the last byte written (or of the queue becoming non-empty). */ uint64 LastProgress() const; private: struct Slot; TCPSFrameQueue(const TCPSFrameQueue &); TCPSFrameQueue &operator=(const TCPSFrameQueue &); void RemoveAt(uint32 i); void Consume(uint32 bytes); Slot **slots; uint32 cap; uint32 depth; uint32 count; uint32 sent; uint64 lastProgress; }; } // namespace MARTe #endif // TCPS_FRAME_QUEUE_H_