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>
80 lines
2.4 KiB
C++
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_
|