CX Framework
Cross-platform C utility framework
Loading...
Searching...
No Matches
win_net_iocp.cxh
1#include <cx/net/queue.cxh>
2#include <cx/platform/win.h>
3
4// Native Windows I/O completion port backend -- the performance target of the whole design.
5//
6// Unlike the readiness backends there is no ingest/dispatch thread split: each completion thread
7// blocks in GetQueuedCompletionStatus, does ingest inline (the buffer is already filled by the
8// kernel), demultiplexes to a flow, reposts a receive, and then drains the runqueue itself. Ingest
9// and dispatch merge on the same thread, so the base class's generic dispatch pool is left unused.
10//
11// The hot UDP socket keeps many WSARecvFrom outstanding so the kernel can hand each completion
12// thread a distinct packet with no thundering herd; a connected stream socket keeps exactly one
13// WSARecv outstanding, since two would complete out of order and corrupt the byte stream.
14
15class NetQueueWinIOCP extends NetQueue
16{
17 // HANDLE to the completion port
18 //
19 // Held as void* so windows.h does not leak into the generated header; cast back to HANDLE in
20 // the implementation.
21 void *iocp;
22
23 // Completion-servicing threads (threaded mode); empty in polled mode
24 //
25 // Each blocks in GetQueuedCompletionStatus and both ingests and dispatches. The base dispatch
26 // pool (NetQueue.workers) stays empty because these threads do that work themselves.
27 [noinit] sarray[Thread] iothreads;
28
29 // Outstanding overlapped operations across every socket
30 //
31 // Each posted receive increments this; each drained completion decrements it. Shutdown cancels
32 // every socket's I/O and then drains completions until this reaches zero, so no pooled buffer
33 // or socket reference is ever stranded in an operation still sitting in the kernel.
34 atomic[uint32] iops;
35
36 // WSARecvFrom operations to keep outstanding on each datagram socket
37 //
38 // Sized from the completion-thread count so every thread can hold a distinct packet with
39 // headroom, floored so a polled queue still pipelines a burst. Fixed at creation.
40 uint32 dgramRecvs;
41
42 // Cached ConnectEx function pointer (LPFN_CONNECTEX), or NULL until first loaded
43 //
44 // ConnectEx is a Winsock extension fetched at runtime via WSAIoctl rather than linked, so it is
45 // looked up once (on the first connect) and cached here. Held as void* so mswsock.h does not
46 // leak into the generated header.
47 void *connectEx;
48
49 // Cached AcceptEx function pointer (LPFN_ACCEPTEX), or NULL until first loaded
50 //
51 // The accept-side counterpart of connectEx: a Winsock extension looked up once via WSAIoctl (on
52 // the first accept) and cached here. Held as void* so mswsock.h does not leak into the header.
53 void *acceptEx;
54
55 factory create(NetQueueConfig *conf);
56
57 // Create a socket compatible with this queue (does not add it).
58 override socket;
59
60 // Associate the socket with the completion port and post its initial receives.
61 override addSocket;
62
63 // Cancel the socket's outstanding operations before it leaves the queue.
64 override removeSocket;
65
66 // Cancel and drain all outstanding I/O, stop the completion threads, then tear down the base.
67 override shutdown;
68
69 // Drain completions on the caller's thread (polled mode).
70 override tick;
71
72 destroy();
73}