Windows-only asynchronous TCP acceptor. windows/TcpAcceptor starts Winsock AcceptEx operations and reports their completion through windows/dispatcher; it is distinct from the fiber-based sync/TcpAcceptor.
Known issue: constructing a TcpAcceptor fails to compile because the module references the unavailable sockaddr_in binding; the compiler reports Name was not found.
Object and construction
TcpAcceptoris one object with an atomicNat8state word, one listening socket, one pending-accept socket, one address buffer, onedispatcher.Context, and one stored callback.INITsets the state word to0n8. Default construction therefore creates an unstarted acceptor; this module has nomakeTcpAcceptorhelper.startListeningcreates and configures the listening socket. A successful call leaves the object inLISTENINGstate.AcceptExis an exportedFN_ACCEPTEXRefslot.startListeningresolves it throughWSAIoctlwhen it is nil.- The module uses the completion port exported by
windows/dispatcher; the dispatcher module initializes Winsock and that completion port at program startup. DIEatomically enters its destruction state and asserts that the state was0n8. Callers must stop listening and finish or cancel an operation before destruction;DIEdoes not close an active listener.
Methods
startListening
(address port -- result) Creates one IPv4 listening socket. address is a host-order Nat32, port is a host-order Nat16, and result is a String, empty on successful setup.Preconditions
- The object state is zero.
Postconditions
- Success sets
TCP_NODELAY, binds and listens, associates the listener with the dispatcher completion port, and setsLISTENING.
stopListening
(--) Closes the owned listening socket and stores the zero state.Preconditions
- The state is exactly
LISTENING, with no acceptance in progress.
accept
(onAccept -- result) Starts one asynchronous AcceptEx operation and returns a String initiation result. onAccept is a Function with source signature ({result: String Ref; connection: TcpConnection Ref;} {} {}) Function; its callback receives the result reference and the accepted windows/TcpConnection reference through that declared input schema. The implementation stores self as the dispatcher context and consumes no separate context stack object.Preconditions
- The state is
LISTENINGand the callback is not nil.
Postconditions
- Success creates the pending connection socket, stores the callback, changes state to
LISTENING | ACCEPTING, and returns an empty string. Completion invokes the callback.
Callback and dispatcher model
acceptdoes not wait for a connection and does not return an address or connection directly. The immediate result reports only whether theAcceptExoperation was initiated.dispatcher.dispatchordispatcher.tryDispatchhandles one completion-port entry. The dispatcher calls the storedonAcceptEventwith transferred bytes and a completion error; the source asserts that the transferred count is zero for this zero-receive accept.- On a successful completion, the source updates the accepted socket with
SO_UPDATE_ACCEPT_CONTEXT, associates it with the completion port, callsTcpConnection.setConnection, and invokesonAccept. - On a failed completion, the source closes the accepted socket and passes either
"canceled"forERROR_OPERATION_ABORTEDor"AcceptEx failed, result="followed by the error code. - The state bits are
IN_DIE=0x01n8,IN_START_LISTENING=0x02n8,IN_STOP_LISTENING=0x04n8,IN_ACCEPT=0x08n8,IN_CANCEL=0x10n8,IN_ON_ACCEPT_EVENT=0x20n8,LISTENING=0x40n8, andACCEPTING=0x80n8.
This callback/dispatcher path differs from sync/TcpAcceptor, whose accept waits in a fiber and returns a connection, address, and result directly.
Ownership and threading
- The acceptor owns its listening socket after successful
startListeningand closes it instopListening. A failed setup path closes the temporary socket and stores zero state. - The accepted socket remains in the acceptor's pending-connection field until completion. On successful completion,
TcpConnection.setConnectioninstalls it in the connection wrapper before the callback is called. - State transitions use
atomicExchange,atomicStore, andatomicXorwith the source's acquire/release markers. Invalid concurrent or out-of-order calls trigger the source assertions. - The module creates no fiber and no worker thread. The thread that calls the dispatcher performs the callback when it dispatches the completion entry.
- The source warns that a caller must synchronize
cancelwith the return fromaccept; cancellation can race the transition into the pending operation.
Results and errors
startListeningreports setup errors as strings beginning withsocket failed, result=,setsockopt failed, result=,bind failed, result=,listen failed, result=,WSAIoctl failed, result=, orCreateIoCompletionPort failed, result=.acceptreports initiation errors withsocket failed, result=,setsockopt failed, result=, orAcceptEx failed, result=.cancelprints a diagnostic whenCancelIoExfails except forERROR_NOT_FOUND; the returned boolean is thenFALSE.- A failed
closesocketprints aLEAK: closesocket failed, result=diagnostic. The source uses assertions for invalid state and callback contracts.
Examples
Windows dispatcher accept
This example does not compile with the checked mpl-sl revision (see the note above), so it carries no Expected Output.
"Function" use
"String" use
"control" use
"windows/TcpAcceptor" use
"windows/TcpConnection" use
"windows/dispatcher" use
{} Int32 {} [
acceptor: TcpAcceptor;
onAccept: ({result: String Ref; connection: TcpConnection Ref;} {} {}) Function;
callback: [connection: result:;;];
@callback @onAccept.assign
result: 0x7F000001n32 6614n16 @acceptor.startListening;
[result.size 0 =] "startListening failed" ensure
acceptResult: @onAccept @acceptor.accept;
[acceptResult.size 0 =] "accept failed" ensure
dispatcher.dispatch
@acceptor.stopListening
0
] "main" exportFunction
See also
- windows/dispatcher: Windows completion-port dispatcher and callback posting helpers.
- windows/TcpConnection: Windows completion-port TCP connection with asynchronous callbacks and cancellation.
- sync/TcpAcceptor: Listening TCP acceptor with address reporting and accepted connection creation.
- windows/ws2_32: Winsock2 declarations for sockets, overlapped I/O, and address-resolution helpers.