Per-connection outbound message queue.
More...
#include <OutboundQueue.hpp>
|
| void | enqueue (uint8_t replaceKey, std::shared_ptr< const std::vector< uint8_t > > framedBytes) |
| | Enqueue a framed message (PR-2 broadcast-friendly form).
|
| void | enqueue (uint8_t replaceKey, std::vector< uint8_t > &&framedBytes) |
| | Convenience overload for the single-client / non-broadcast case.
|
| bool | flushTo (NET_StreamSocket *socket, Uint32 maxAgeMs) |
| | Drain the queue, writing each entry to socket.
|
| size_t | depth () const noexcept |
| | Number of entries currently queued (for telemetry / tests).
|
| size_t | totalBytes () const noexcept |
| | Total bytes across all queued entries (for telemetry).
|
| void | clear () noexcept |
| | Drop all queued entries (used on disconnect).
|
Per-connection outbound message queue.
PR-5b (server-perf): the queue is self-locked. Pre-PR-5b the caller (Server::flushAllOutbound, Server::enqueueBroadcast, etc.) had to hold the global stateMutex_ for every operation, which meant the network thread's per-cycle flush serialized with every game-thread broadcast. With the internal mutex, the global lock can be released while the queue is doing its slow work (NET_WriteToStreamSocket syscalls inside flushTo) — multiple game-thread enqueues can land on different clients while the network thread is mid-flush of another client's queue.
The mutex is mutable so const observers (depth, totalBytes) can take it; in practice they're only called from telemetry paths where the brief lock is fine.
◆ clear()
| void OutboundQueue::clear |
( |
| ) |
|
|
inlinenoexcept |
Drop all queued entries (used on disconnect).
◆ depth()
| size_t OutboundQueue::depth |
( |
| ) |
const |
|
inlinenodiscardnoexcept |
Number of entries currently queued (for telemetry / tests).
◆ enqueue() [1/2]
| void OutboundQueue::enqueue |
( |
uint8_t | replaceKey, |
|
|
std::shared_ptr< const std::vector< uint8_t > > | framedBytes ) |
Enqueue a framed message (PR-2 broadcast-friendly form).
- Parameters
-
| replaceKey | See OutboundEntry::replaceKey. |
| framedBytes | Shared owning pointer to the bytes. Must already include the 4-byte length prefix that MessageStream uses for framing — this class doesn't add it. PR-2: shared_ptr lets a single snapshot fan out to N clients with N pointer copies and zero data copies. |
◆ enqueue() [2/2]
| void OutboundQueue::enqueue |
( |
uint8_t | replaceKey, |
|
|
std::vector< uint8_t > && | framedBytes ) |
Convenience overload for the single-client / non-broadcast case.
Wraps the rvalue vector into a fresh shared_ptr internally. Callers that already hold a shared_ptr should prefer the form above to avoid the wrap.
◆ flushTo()
| bool OutboundQueue::flushTo |
( |
NET_StreamSocket * | socket, |
|
|
Uint32 | maxAgeMs ) |
Drain the queue, writing each entry to socket.
Entries older than maxAgeMs are dropped if their replaceKey is non-zero (i.e. unreliable-style snapshot/state). Reliable entries with replaceKey == 0 are always shipped regardless of age.
- Parameters
-
| socket | SDL3_net stream socket to write to. |
| maxAgeMs | Drop unreliable entries older than this (0 = no culling). Plan default: 300 ms. |
- Returns
- False on socket error (caller should disconnect the client).
◆ totalBytes()
| size_t OutboundQueue::totalBytes |
( |
| ) |
const |
|
nodiscardnoexcept |
Total bytes across all queued entries (for telemetry).
◆ entries_
◆ mutex_
| std::mutex OutboundQueue::mutex_ |
|
mutableprivate |
PR-5b: protects entries_ for cross-thread access.
The documentation for this class was generated from the following files: