Implementation base class for the transport operations on a datagram socket.
Implementations are required to call the following hooks on socket lifecycle events:
WakeReader() when data arrives from the peer.WakeOneWriter() or WakeAllWriters() when space becomes available for writing.MarkClosed() when the socket is closed by any means.The DoCancelWrite operation has a default no-op implementation. Implementations should override it if supported.
Implementations must handle the closed socket state across read, write, reserve, and close operations.
Subclasses provide synchronization by implementing lock() and unlock(). Implementations of the protected virtual methods (DoRead, DoCommitWrite, DoCancelWrite, DoClose, DoTryReserveWrite) are called while the socket lock is held. Subclasses must NOT call public methods on SocketImpl (such as CommitWrite, CancelWrite, TryReserveWrite, Close, or Adopt) from within these callbacks, as doing so will attempt to re-acquire the lock and cause a deadlock when using non-recursive locks.
Public Types | |
| enum class | State : uint8_t { kOpen , kClosing , kClosed } |
Public Member Functions | |
| virtual void | lock () const =0 |
| virtual void | unlock () const =0 |
| State | state () const |
| bool | is_open () const |
| bool | is_closed () const |
| bool | is_closing () const |
| size_t | max_write_message_size_bytes () const |
| size_t | max_read_message_size_bytes () const |
| ReadFuture | Read () |
| ReserveWriteFuture | ReserveWrite (size_t min_size_bytes) |
Reserves write space for a datagram of at least min_size_bytes. | |
| std::optional< WriteReservation > | TryReserveWrite (size_t min_size_bytes) |
| CloseFuture | Close () |
| Closes the socket, resolving once teardown is complete. | |
| CloseFuture | WhenClosed () |
| Resolves when the socket is closed. | |
| bool | CommitWrite (Buf buffer) |
| void | CancelWrite (Buf buffer) |
Protected Member Functions | |
| constexpr | SocketImpl (Allocator &allocator, size_t max_write_message_size_bytes, size_t max_read_message_size_bytes) |
| constexpr | SocketImpl (Allocator &allocator, size_t max_message_size_bytes) |
| Socket | WrapSocket () |
| void | MarkClosed () |
| void | WakeReader () |
Wakes any pending ReadFuture. | |
| void | WakeOneWriter () |
| void | WakeAllWriters () |
| WriteReservation | CreateReservation (Buf &&buffer=Buf::ZeroLength()) |
| void | Adopt (WriteReservation &reservation, size_t prefix_trim=0, size_t suffix_trim=0) |
| void | AdoptLocked (WriteReservation &reservation, size_t prefix_trim=0, size_t suffix_trim=0) |
Private Member Functions | |
| virtual async2::Poll< ConstBuf > | DoRead ()=0 |
| virtual std::optional< WriteReservation > | DoTryReserveWrite (size_t min_size_bytes)=0 |
| virtual void | DoClose ()=0 |
| virtual bool | DoCommitWrite (Buf &&buffer)=0 |
| virtual void | DoCancelWrite (Buf &&) |
Friends | |
| class | Socket |
| class | WriteReservation |
| class | Recyclable< SocketImpl > |
| class | ReadFuture |
| class | ReserveWriteFuture |
| class | CloseFuture |
| class | internal::BaseSocketFuture |
|
inlineconstexprprotected |
Base constructor for an allocated, ref-counted socket. The socket is automatically destroyed and freed once no active Socket handles or futures reference it.
|
inlineprotected |
Associates an existing WriteReservation with this socket, slicing the buffer to reserve space for protocol headers and footers.
| void pw::transport::SocketImpl::CancelWrite | ( | Buf | buffer | ) |
Cancels a write reservation.
Takes ownership of buffer by value to ensure that the buffer is released.
| bool pw::transport::SocketImpl::CommitWrite | ( | Buf | buffer | ) |
Commits buffer for transmission. Returns false if the socket is closed or transmission fails.
Takes ownership of buffer by value to ensure that the buffer is released upon return even if transmission fails or the socket is closed.
|
inlineprotected |
Factory method for subclasses to create reservations.
buffer must not be null (buffer != nullptr).
|
inlineprivatevirtual |
Cancels a write reservation. Called with *this locked.
buffer is passed by rvalue reference to minimize moves. If not consumed, CancelWrite will destroy and release it upon return.
|
privatepure virtual |
Implements closing the socket. Called with *this locked.
Implementers are required to call MarkClosed once teardown is completed.
*this locked, implementations that interact with peer sockets or lower layers must take care to avoid cross-socket AB-BA deadlocks if both sockets close concurrently from different threads.
|
privatepure virtual |
Commits buffer for transmission. Called with *this locked.
*this locked, forwarding data to other sockets (e.g. in layered transports, bridges, or paired peer sockets) creates an AB-BA deadlock hazard if the target socket attempts to transmit back or synchronize in reverse order.buffer is passed by rvalue reference to minimize moves while allowing the driver to take ownership (e.g. by moving it into a hardware transmission queue). If the driver does not consume buffer, CommitWrite guarantees that it will be destroyed and released upon return.
|
privatepure virtual |
Implements reading a single datagram from the peer. Called from ReadFuture::Pend with *this locked.
A received zero-length datagram must be returned as a non-null empty ConstBuf (such as ConstBuf::ZeroLength()), since a null ConstBuf indicates that the socket is closed.
|
privatepure virtual |
Implements synchronously reserving write space of at least min_size_bytes. Called with *this locked.
When min_size_bytes is 0, implementations that do not need header or footer space in the buffer may pass Buf::ZeroLength() to CreateReservation().
|
protected |
Marks the socket as closed, resolving any pending Close() or WhenClosed() futures.
|
inline |
Receives a single datagram from the peer. Resolves to a null ConstBuf if the socket is closed.
| std::optional< WriteReservation > pw::transport::SocketImpl::TryReserveWrite | ( | size_t | min_size_bytes | ) |
Synchronously attempts to reserve write space for a datagram of at least min_size_bytes.
|
inlineprotected |
Wakes all pending ReserveWriteFutures. Should be called when space becomes available for writing.
|
inlineprotected |
Wakes one pending ReserveWriteFuture. Should be called whenever space becomes available for writing.