Files
MARTe-Integrated-Components/Source/Components/Interfaces/TCPStreamService/TCPSFrameQueue.h
T
Martino FerrariandClaude Opus 4.6 50d85363a3 feat(tcp): TCPStreamer DataSources, in-process TCPStreamService, stream multiplexing and TCPStreamJoin
Add TCPStreamer/TCPStreamerClient (TCP transport behind the UDPSServerI/UDPSClientI
seam), an optional single in-process TCPStreamService serving many streams over
worker threads, multiplexed SUBSCRIBE (comma list, stream index in fragmentIdx),
and TCPStreamJoin, which merges several streams into one sample-and-hold stream
paced by a master. StreamHub takes a comma list of streams over one connection.
Includes GTests, E2E scenarios s58-s73 and docs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-11-06 13:41:27 +01:00

80 lines
2.4 KiB
C++

#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_