eve.backend.windows.iocp

Windows Layer 0 readiness backend built on IOCP and WSAPoll.

This backend uses Windows I/O Completion Ports as the core notification mechanism while leveraging WSAPoll for socket readiness detection. The combination provides an IOCP-based architecture with readiness semantics suitable for the Layer 0 abstraction.

Key features:

  • WSAPoll-based socket readiness polling (reliable, tested)
  • Handle type classification for future non-socket support
  • IOCP-based wakeup mechanism via PostQueuedCompletionStatus
  • Unified wait combining IOCP wakeups with socket polling

Types 9

enumHandleType : ubyte

Handle type classification.

Different handle types require different polling mechanisms on Windows. Currently, only sockets are fully supported via WSAPoll. Other handle types are classified for future IOCP-based overlapped I/O support.

UNKNOWN = 0Unknown or invalid handle type.
SOCKET = 1Socket handle (uses WSAPoll for readiness).
CONSOLE = 2Console input handle (future: WaitForSingleObject or ReadConsoleInput).
PIPE = 3Named pipe handle (future: overlapped I/O via IOCP).
FILE = 4File handle (future: overlapped I/O via IOCP).
EVENT = 5Event handle (future: WaitForSingleObject).
enumIoModel : ubyte

I/O model used for a registered handle.

Determines how the handle is polled for readiness or completion.

POLLUse WSAPoll for readiness polling (sockets only).
OVERLAPPEDUse IOCP overlapped I/O for completion notification.
enumIoOperation : ubyte

Type of I/O operation for overlapped tracking.

NONENo operation in progress.
READRead operation pending.
WRITEWrite operation pending.
ACCEPTAccept operation pending (sockets).
CONNECTConnect operation pending (sockets).

Entry in the overlapped I/O pool.

Each entry contains an OVERLAPPED structure, a data buffer, and metadata for tracking the operation. The entry must remain valid until the I/O operation completes. Entry in the overlapped I/O pool.

Each entry contains an OVERLAPPED structure and metadata for tracking the operation. Buffers are provided externally by the caller. The entry must remain valid until the I/O operation completes.

Fields
OVERLAPPED overlappedWindows OVERLAPPED structure for async I/O.
ulong userDataUser data associated with this operation.
HANDLE handleHandle this operation is associated with.
void * bufferPtrPointer to external buffer (owned by caller).
size_t bufferSizeSize of the external buffer.
IoOperation operationType of operation in progress.
bool inUseWhether this entry is currently in use.
size_t bytesTransferredNumber of bytes transferred (filled on completion).
Methods
void reset() @trusted nothrow @nogcReset the OVERLAPPED structure for reuse.

Pool of pre-allocated OVERLAPPED entries for async I/O.

This pool manages the lifecycle of OVERLAPPED structures used for Windows overlapped I/O operations. Entries are acquired before submitting an I/O operation and released when the operation completes.

Fields
OverlappedEntry[MAX_OVERLAPPED_ENTRIES] _entries
size_t _activeCount
Methods
OverlappedEntry * acquire() @trusted nothrow @nogcAcquire an entry from the pool.
void release(OverlappedEntry * entry) @trusted nothrow @nogcRelease an entry back to the pool.
OverlappedEntry * findByOverlapped(OVERLAPPED * overlappedPtr) @trusted nothrow @nogcFind an entry by its OVERLAPPED pointer.
size_t activeCount() @property const pure @safe nothrow @nogcGet the number of active (in-use) entries.
bool hasAvailable() @property const pure @safe nothrow @nogcCheck if the pool has available entries.
private enumCompletionKey : ULONG_PTR

Special completion keys for internal IOCP events.

WAKEUP = 0xFFFF_FFFEWakeup signal from another thread.
TIMER = 0xFFFF_FFFDInternal timer expiration (future use).
SHUTDOWN = 0xFFFF_FFFCShutdown signal.

Native event type returned by this backend.

Mirrors the shape used by the epoll backend to maintain a consistent interface for Layer 1 consumption.

Fields
uint eventsReadiness event mask in epoll-compatible format.
Methods
inout(Data) data() @property ref return inout pure @safe nothrow @nogcAccess the user data union.
Nested Templates
DataNested data union for compatibility.
private structRegistration

Registration entry for a handle.

Fields
SOCKET socketThe native socket value (for WSAPoll).
HANDLE nativeHandleNative handle for non-socket handles.
HandleType handleTypeType of handle registered.
IoModel ioModelI/O model used for this handle.
IoInterest interestRequested readiness interests.
ulong userDataUser-provided opaque data.
bool activeWhether this slot is actively registered.
structOsPoller

IOCP-backed poller state for Windows.

This backend maintains an I/O Completion Port handle for the notification mechanism and uses WSAPoll internally for socket readiness detection. The IOCP is also used for efficient cross-thread wakeups.

Fields
void * _iocp
Registration[maxRegistrations] _registrations
WSAPOLLFD[maxRegistrations] _pollFds
size_t[maxRegistrations] _pollToReg
OverlappedPool _overlappedPool
size_t _registrationCount
size_t _socketCount
size_t _overlappedCount
bool _winsockInitialized
bool _pendingWakeup
Methods
OsPoller create() @trusted nothrow @nogcCreate a new IOCP-based poller.
bool isValid() @property const pure @safe nothrow @nogcCheck whether the poller has a valid IOCP handle.
Handle handle() @property const pure @trusted nothrow @nogcReturn the native handle wrapper for the IOCP instance.
size_t registrationCount() @property const pure @safe nothrow @nogcGet the number of active registrations.
size_t overlappedCount() @property const pure @safe nothrow @nogcGet the number of overlapped (non-poll) registrations.
OverlappedPool overlappedPool() @property ref return @safe nothrow @nogcGet the overlapped entry pool.
int dispose() @trusted nothrow @nogcClose the IOCP instance and release resources.
int registerHandle(Handle handle, IoInterest interest, ulong userData) @trusted nothrow @nogcRegister a handle with the given interests and opaque user data.
int modifyHandle(Handle handle, IoInterest interest, ulong userData) @trusted nothrow @nogcModify the interest mask and user data for an already-registered handle.
int unregisterHandle(Handle handle) @trusted nothrow @nogcRemove a handle from the registration table.
bool postWakeup() @trusted nothrow @nogcPost a wakeup event to the IOCP.
int associateHandle(HANDLE handle, ulong completionKey) @trusted nothrow @nogcAssociate a handle with the IOCP for overlapped I/O.
int wait(scope NativeEvent[] nativeEvents, int timeoutMs) @trusted nothrow @nogcWait for native events.
OsEvent translate(ref const(NativeEvent) nativeEvent) pure @safe nothrow @nogcTranslate a native event into the shared Layer 0 event shape.
IoReady translateReady(uint nativeMask) pure @safe nothrow @nogcTranslate a native readiness mask into shared readiness flags.
void checkPendingIocpEvents() @trusted nothrow @nogcCheck for pending IOCP events without blocking.

Functions 3

private fnshort toNativeMask(IoInterest interest) pure @safe nothrow @nogcConvert IoInterest to native WSAPoll mask.
private fnuint toEpollMask(short pollMask) pure @safe nothrow @nogcConvert WSAPoll revents mask to epoll-compatible mask.
private fnIoReady fromNativeMask(uint mask) pure @safe nothrow @nogcConvert epoll-compatible mask to shared IoReady flags.

Variables 2

private enumvarmaxRegistrations = 1024

Maximum number of registrations supported.

This limit applies to the total number of handles (sockets, pipes, files) that can be registered with a single event loop. If your application needs more than 1024 concurrent I/O watchers, you may need to use multiple event loops or restructure your application.

Note

This is a compile-time constant due to fixed-size array allocation.

Future versions may support dynamic sizing via EventLoopConfig.watcherCapacity.

private enumvarMAX_OVERLAPPED_ENTRIES = 64

Maximum number of overlapped entries in the pool.