Retrieving Completed I/O Events from the Port
Now that we know how to create a completion port, associate descriptors to it, and initiate asynchronous I/O operations on the descriptors, it's on to retrieving completion events from the port. A thread removes an event from the port's queue by calling the
BOOL GetQueuedCompletionStatus( HANDLE CompletionPort, LPDWORD pNumberOfBytes, PULONG_PTR pCompletionKey, LPOVERLAPPED* ppOverlapped, DWORD Timeout );
Obviously, the first parameter to this function is the handle to the
port object, followed by several pointers and a
Timeout value. Once an operation has completed successfully, the variable pointed to by
pNumberOfBytes contains the number of bytes written or read during the I/O completion, the
pCompletionKey value contains the value of the completion key passed when associating the file descriptor to the port, and the
ppOverlapped variable points to the OVERLAPPED pointer passed as the parameter to the asynchronous I/O function. The
timeout value, which is specified in milliseconds, works just like other Windows functions in that the special value INFINITE may be passed to specify "wait forever."
Sending Your Own Events: PostQueuedCompletionStatus
Before we move on to a practical example, there's one more function to discuss:
BOOL PostQueuedCompletionStatus( HANDLE CompletionPort, DWORD NumberOfBytesTransferred, ULONG_PTR CompletionKey, LPOVERLAPPED pOverlapped );
This function lets you post completion events to the port. Typically, this function is used to send implementation-specific messages to the port. When you post a completion event to a port, one of the threads blocking on the port successfully returns from its call to
GetQueuedCompletionStatus with copies of the parameters as they were posted.
This function is often used to notify worker threads of some global or application-wide event. Along those lines, the sample program presented in this article posts completion events with a special completion key value of COMPLETION_KEY_SHUTDOWN in order to tell the worker threads that the server is shutting down.