Windows completion-port dispatcher object that multiplexes posted callbacks and overlapped completions. The object provides callback posting, blocking or polling dispatch, one wake helper, and one exported opaque completion-port handle.
Windows-only.
Dispatcher objects
dispatcherInternal and dispatcher refer to the same initialized Windows completion-port dispatcher object. dispatcherInternal is the mutable module-level object used for initialization and cleanup; dispatcher is the public alias that pushes an immutable view of it for callers.
dispatcherInternal
(-- dispatcherInternal) Provides the initialized dispatcher object.Remarks
- This is the mutable top-level object used for module initialization and cleanup. Callers normally use
dispatcher.
Fields
OnCallback: callbackCodeschema with inputcontext:Natxand no output.OnEventRef: callbackCodeschema with inputscontext:Natx,numberOfBytesTransferred:Nat32, anderror:Nat32, and no output. TheonEventcallback stack has the byte count deepest, then the error code, with context on top; the declared field names ofOnEventRefare in the other order.Context: schema withoverlapped:OVERLAPPED,onEvent: OnEventRef, andcontext:Natx. Keep each instance and its embedded overlapped storage alive until its completion is dispatched.completionPort: the opaque completion-port handle asNatx.DIE: lifetime hook that stops Winsock and closes the completion port.
Queue entry forms at a glance
| Entry form | Completion key | lpOverlapped |
Dispatched callback | User payload source |
|---|---|---|---|---|
| Posted callback | Callback Code address |
Pointer slot carrying the Natx context value |
OnCallback, called with that value as context |
The caller's Natx context value |
| Overlapped completion | 0nx |
Address of Context.overlapped |
Context.onEvent |
Context.context, OVERLAPPED.Internal, and transferred bytes |
Operations
init
(--) Initializes the dispatcher completion port and Winsock state.- The module invokes it once during program startup; it is an ordinary method named
init, not an INIT hook.
Remarks
- Use the already initialized global object. Do not reinitialize it or call its DIE cleanup manually; reinitialization replaces the stored handle without first closing it, and DIE does not clear that handle.
dispatch
(--) Waits for one completion-port entry and dispatches exactly one callback.Known issue: processing dispatcher.dispatch fails at compile time because the dispatcher uses INFINITE without importing "kernel32.INFINITE", reporting «INFINITE», Name was not found.
- Requests at most one entry with an infinite timeout. A posted callback and an overlapped completion use the two queue-entry forms above.
- Checks that exactly one entry was returned.
- A failed wait prints
FATAL: GetQueuedCompletionStatusEx failed, result=followed by the Win32 error and exits with status 1.
tryDispatch
(-- handled) Polls the completion port once and reports whether one entry was dispatched.- Polls with zero timeout. A timeout returns
FALSE; one dispatched entry returnsTRUE. - A non-timeout wait failure prints
FATAL: GetQueuedCompletionStatusEx failed, result=followed by the Win32 error and exits with status 1. - Successful processing uses the same callback and one-entry assertions as
dispatch.
contextis an opaqueNatxpayload carried in the queued pointer slot and passed unchanged toOnCallback; it can be zero. The posted-entry dispatch branch does not dereference it asOVERLAPPED. If the callback treats the value as an address, keep the addressed object alive and valid until the callback finishes. Posting does not copy or take ownership of that object.- The callback address becomes the completion key;
PostQueuedCompletionStatusreceives the context value in its pointer slot and zero transferred bytes. - A failed post prints
FATAL: PostQueuedCompletionStatus failed, result=followed by the Win32 error and exits with status 1.
Remarks
postchecks only that the callback is non-NIL, reportingdispatcher.post: invalid callbackwhen checked. It does not verify the callback signature. Supply aCodeobject with theOnCallbacksignature, consuming oneNatxcontext and returning no objects.OnCallbackandOnEventRefproduceNILCode prototypes. Assign a compatible callable before use. InitializeContext.onEventto a non-NILOnEventRefcallback before submitting overlapped work; the overlapped dispatch branch does not perform the post NIL check.
- Its intended use is to release one blocked dispatch wait without an application callback.
Known issue: calling wakeOne fails compilation with «drop», Name was not found.
Dispatch model
- The queue is a Windows I/O completion port created by the module. A queued task is either a posted callback entry or an overlapped-I/O completion entry.
- The module creates no thread and does not own a worker. The thread that calls
dispatchortryDispatchexecutes the selected callback. - Each successful poll or wait processes one queue entry.
- Dispatch checks the returned entry count and the transferred count against
OVERLAPPED.InternalHigh, reportingunexpected actual entry countorunexpected transferred size. Run-time assertions requireDEBUG; known violations can still fail compilation whenDEBUGis disabled.
Initialization and cleanup
- Initialization creates one completion port with
INVALID_HANDLE_VALUEand zero completion key, then callsWSAStartupfor version0x0202. - If completion-port creation fails, initialization prints
FATAL: CreateIoCompletionPort failed, result=followed byGetLastErrorand exits with status 1. - If Winsock startup fails, initialization prints
FATAL: WSAStartup failed, result=followed by the returned result and exits with status 1. - Destroying the dispatcher calls
WSACleanupand closescompletionPort. Cleanup failures printLEAK: WSACleanup failed, result=orLEAK: CloseHandle failed, result=followed by the corresponding error value.
Examples
Windows polling example
"String" use
"control" use
"windows/dispatcher" use
{} Int32 {} [
handled: dispatcher.tryDispatch;
("handled=" handled LF) printList
0
] "main" exportFunction
Expected Output
handled=FALSE
See also
- windows/kernel32: Kernel32 declarations for synchronization, process, thread, file, and timing helpers.
- windows/ws2_32: Winsock2 declarations for sockets, overlapped I/O, and address-resolution helpers.
- sync/sync: Cross-platform scheduling, sleep, time, IPv4 formatting, and TCP helpers.
- sync/Context: Spawned context handle with waiting, output retrieval, and cancellation.
- sync/Event: Persistent event state with clear, set, wait, wake, and wakeOne.