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>
This commit is contained in:
1 parent
5562877c99
commit
50d85363a3
79 files changed
+12348
-138
No files matched your search
@@ -0,0 +1,79 @@
|
||||
#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_
|
||||
Reference in new issue
Block a user