5 out of 13 rated this helpful - Rate this topic

GetQueuedCompletionStatus function

Applies to: desktop apps only

Attempts to dequeue an I/O completion packet from the specified I/O completion port. If there is no completion packet queued, the function waits for a pending I/O operation associated with the completion port to complete.

To dequeue multiple I/O completion packets at once, use the GetQueuedCompletionStatusEx function.

Syntax

BOOL WINAPI GetQueuedCompletionStatus(
  __in   HANDLE CompletionPort,
  __out  LPDWORD lpNumberOfBytes,
  __out  PULONG_PTR lpCompletionKey,
  __out  LPOVERLAPPED *lpOverlapped,
  __in   DWORD dwMilliseconds
);

Parameters

CompletionPort [in]

A handle to the completion port. To create a completion port, use the CreateIoCompletionPort function.

lpNumberOfBytes [out]

A pointer to a variable that receives the number of bytes transferred during an I/O operation that has completed.

lpCompletionKey [out]

A pointer to a variable that receives the completion key value associated with the file handle whose I/O operation has completed. A completion key is a per-file key that is specified in a call to CreateIoCompletionPort.

lpOverlapped [out]

A pointer to a variable that receives the address of the OVERLAPPED structure that was specified when the completed I/O operation was started.

Even if you have passed the function a file handle associated with a completion port and a valid OVERLAPPED structure, an application can prevent completion port notification. This is done by specifying a valid event handle for the hEvent member of the OVERLAPPED structure, and setting its low-order bit. A valid event handle whose low-order bit is set keeps I/O completion from being queued to the completion port.

dwMilliseconds [in]

The number of milliseconds that the caller is willing to wait for a completion packet to appear at the completion port. If a completion packet does not appear within the specified time, the function times out, returns FALSE, and sets *lpOverlapped to NULL.

If dwMilliseconds is INFINITE, the function will never time out. If dwMilliseconds is zero and there is no I/O operation to dequeue, the function will time out immediately.

Return value

Returns nonzero (TRUE) if successful or zero (FALSE) otherwise.

To get extended error information, call GetLastError.

For more information, see the Remarks section.

Remarks

This function associates a thread with the specified completion port. A thread can be associated with at most one completion port.

If a call to GetQueuedCompletionStatus fails because the completion port handle associated with it is closed while the call is outstanding, the function returns FALSE, *lpOverlapped will be NULL, and GetLastError will return ERROR_ABANDONED_WAIT_0.

Windows Server 2003 and Windows XP:  Closing the completion port handle while a call is outstanding will not result in the previously stated behavior. The function will continue to wait until an entry is removed from the port or until a time-out occurs, if specified as a value other than INFINITE.

If theGetQueuedCompletionStatus function succeeds, it dequeued a completion packet for a successful I/O operation from the completion port and has stored information in the variables pointed to by the following parameters: lpNumberOfBytes, lpCompletionKey, and lpOverlapped. Upon failure (the return value is FALSE), those same parameters can contain particular value combinations as follows:

  • If *lpOverlapped is NULL, the function did not dequeue a completion packet from the completion port. In this case, the function does not store information in the variables pointed to by the lpNumberOfBytes and lpCompletionKey parameters, and their values are indeterminate.
  • If *lpOverlapped is not NULL and the function dequeues a completion packet for a failed I/O operation from the completion port, the function stores information about the failed operation in the variables pointed to by lpNumberOfBytes, lpCompletionKey, and lpOverlapped. To get extended error information, call GetLastError.

For more information on I/O completion port theory, usage, and associated functions, see I/O Completion Ports.

Requirements

Minimum supported client

Windows XP

Minimum supported server

Windows Server 2003

Header

WinBase.h (include Windows.h)

Library

Kernel32.lib

DLL

Kernel32.dll

See also

Overview Topics
File Management Functions
I/O Completion Ports
Using the Windows Headers
Functions
ConnectNamedPipe
CreateIoCompletionPort
DeviceIoControl
GetQueuedCompletionStatusEx
LockFileEx
ReadFile
PostQueuedCompletionStatus
TransactNamedPipe
WaitCommEvent
WriteFile

 

 

Send comments about this topic to Microsoft

Build date: 4/17/2012

Did you find this helpful?
(1500 characters remaining)
Community Content Add
Annotations FAQ
Earliest supported OS is wrong
GetQueuedCompletionStatus works in the field today on NT 4.0 and Windows 2000.
What happened before Vista?
"Starting with Windows Vista, if a call to GetQueuedCompletionStatus fails because the handle associated with it is closed, the function returns FALSE and GetLastError will return ERROR_ABANDONED_WAIT_0."
Good to know, but what happened _before_ Vista?

Also, "the handle associated with it is closed" should read "a handle associated with the completion port is closed". A completion port can be associated with 0-n handles, so "the" is wrong. Also, "it" refers to GetQueuedCompletionStatus, and "with GetQueuedCompletionStatus is closed" is wrong and doesnt make any sense.

What happened before Vista?
I believe before Vista, GetQueuedCompletionStatus returned TRUE, with *lpOverlaped non-NULL and lpNumberOfBytes equal to zero. This was supposedly documented in MSDN Library before. If so, someone who thought the whole world suddenly is using Vista must have removed it?!?

One other thing: all this stuff about what to do when a handle associated with a completion port is closed is just weird. The most sensible thing would be to not return at all when this happends (should have had a BOOL param to speficy desired behaviour). A problem with the Vista behaviour is you probably won't get the completion key when a handle is closed (so you knew what was closed).
Distinguishing GetQueuedCompletionStatus() failure from I/O operation failure
The Return Value section definitely needs improvement. Aside from the differences between the Return Value and Remarks sections, it doesn't cover what happens when the call to GetQueuedCompletionStatus() fails. And they aren't consistent in the type of the return value (BOOL versus int).

It makes it vaguely clear that a 0/FALSE return value can indicate either that the GetQueuedCompletionStatus() function failed or there was an I/O operation failure (with full details in the variables). According to the code in "Windows via C/C++" 5th edition on p.325, if lpOverlapped is NULL, the GetQueuedCompletionStatus() function failed (such as a bad handle). If it is not NULL, there was a failed I/O operation (e.g. "Disk Full").

Return Value section is confusingly worded

I suggest the following wording:

Return Value

The return value indicates whether a successful I/O operation was dequeued from the completion port. If the function dequeues a completion packet for a successful I/O operation from the completion port, the return value is nonzero. The function stores information in the variables pointed to by the lpNumberOfBytes, lpCompletionKey, and lpOverlapped parameters.

Otherwise, the function returns zero. If *lpOverlapped is NULL, the function has not dequeued a completion packet from the completion port. The function does not store information in the variables pointed to by the lpNumberOfBytes and lpCompletionKey parameters. To get extended error information, call GetLastError. If the function did not dequeue a completion packet because the wait timed out, GetLastError returns WAIT_TIMEOUT.

If *lpOverlapped is not NULL, the function has dequeued a completion packet for a failed I/O operation from the completion port. The function stores information in the variables pointed to by lpNumberOfBytes, lpCompletionKey, and lpOverlapped. To get extended error information, call GetLastError.