GetMultipleCompletionStatus Subroutine


Dequeues multiple completion packets from a specified I/O completion port.


#include <sys/iocp.h>
int GetMultipleCompletionStatus (CompletionPort, Nmin, Nmax, Timeout, Results[])
HANDLE CompletionPort;
DWORD Nmin, Nmax, Timeout;
struct gmcs {
    DWORD transfer_count, completion_key, errorno;
    LPOVERLAPPED overlapped;
} Results[];


The GetMultipleCompletionStatus subroutine attempts to dequeue a number of completion packets from the completion port that is specified by the CompletionPort parameter. The number of dequeued completion packets that are wanted ranges from the value of the Nmin parameter through the value of the Nmax parameter. As it collects the packets, this subroutine might wait a predetermined maximum amount of time that is specified by the Timeout parameter for the minimum number of completion packets to arrive. If, for example, the Xth completion packet does not arrive in time, the subroutine returns with only X-1 packets completed.

Either the Timeout parameter or a signal might cause a return with completions fewer than the value of the Nmin parameter. In other words, Nmin completions are not guaranteed to be returned unless the Timeout parameter value is set to INFINITE, and a signal does not interrupt the wait. The return of zero completions is not considered an error. The errno value will, however, indicate the condition with either the ETIMEDOUT or EINTR error code. In extreme low-memory situations, the kernel might not be able to provide a timeout. In this case, the system call returns immediately with any available completions, up to the value of the Nmax parameter, and the errno value is set to ENOMEM. Be sure to set the errno value to zero before calling the GetMultipleCompletionStatus subroutine so that the change of the errno value that the subroutine makes can be distinguished from the existing value.

The GetMultipleCompletionStatus subroutine is part of the I/O Completion Port (IOCP) kernel extension.

  1. This subroutine only works with file descriptors of sockets, or regular files for use with the asynchronous I/O subsystem. It does not work with file descriptors of other types.
  2. This function must be the exclusive wait mechanism on a completion port. Multiple simultaneous waits through the GetMultipleCompletionStatus subroutine, the GetQueuedCompletionStatus subroutine, or both, are not supported.
  3. When the GetMultipleCompletionStatus subroutine is used with the lio_listio subroutine, you can set the value of the cmd parameter of the lio_listio subroutine to LIO_NOWAIT_GMCS to avoid asynchronous updating of the aiocb structures, thereby reducing overhead. In this case, you must use the GetMultipleCompletionStatus subroutine to wait for I/O completions, and retrieve completion status only from the struct gmcs members, not from the aiocb structure. When using the LIO_NOWAIT_GMCS value, do not use the completion_key value in the gmcs structure. Do not use the LIO_NOWAIT_AIOWAIT value with the lio_listio subroutine when using the GetMultipleCompletionStatus subroutine. The LIO_NOWAIT_GMCS value is available for that purpose.
  4. Cancelling an asynchronous I/O operation will not affect the GetMultipleCompletionStatus subroutine. Even if the cancelling reduces the number of active asynchronous I/O operations to zero, the subroutine will continue to wait.
  5. When using the GetMultipleCompletionStatus subroutine with sockets, do not wait for multiple completions (Nmin > 1) with an INFINITE timeout. Use a finite timeout value, and to be prepared to repeat the call if additional completions are still expected.


Item Description Attribute description
CompletionPort Specifies the file descriptor for the completion port that this subroutine will access.  
Nmin Specifies the minimum number of completions. Fewer might be returned if the value of the timeout parameter is exceeded, or a signal accepted. More might be returned, up to the number that is specified by the Nmax parameter, if additional completions have occurred. Setting the value of the Nmin parameter to zero will poll for completions and return immediately, ignoring the value of the timeout parameter.  
Nmax Specifies the maximum number of completions to wait for, up to the value of the GMCS_NMAX macro.  
Results This is the address of an array of the gmcs structure to receive the completion data. The array must contain space for the number of entries specified by the Nmax parameter.  
  Results[i]. transfer_count Specifies the number of bytes transferred. This parameter is set by the subroutine from the value received in the ith completion packet. This value is limited to 2 G.
  Results[i].completion_key Specifies the completion key associated with the file descriptor that is used in the transfer request. This parameter is set by the subroutine from the value received in the ith completion packet. Do not use this value with the LIO_NOWAIT_GMCS command parameter of the lio_listio subroutine.
  Results[i].errorno Specifies the errno value that is associated with the ith completion packet. When asynchronous I/O requests are started using the lio_listio subroutine with the LIO_NOWAIT_GMCS command parameter, you must use this error value, not the aio_errno member in the aiocb structure, to retrieve the error value that is associated with an I/O request.
  Results[i].overlapped Specifies the overlapped structure that is used in the transfer request. This parameter is set by the subroutine from the value received in the ith completion packet. For regular files, this parameter contains a pointer to the asynchronous I/O control block (AIOCB) for a completed AIO request. If an application uses the same completion port for both socket and AIO to regular files, it must use unique completion_key values to differentiate between sockets and regular files to properly interpret the overlapped parameter.
Timeout Specifies the amount of time in milliseconds that the subroutine is to wait for completion packets. This value can be set to zero. If this parameter is set to INFINITE, the subroutine will never time out.  

Return Values

Item Description
Success The subroutine returns an integer ranging from zero through the value of the Nmax parameter, indicating how many completion packets are dequeued.
Failure The subroutine returns a value of -1.

Error codes

The subroutine is unsuccessful if any of the following errors occur:

Item Description
EINVAL The value of the CompletionPort or other parameter is not valid.
EBUSY Another thread is already waiting on the I/O completion port.
EBADF This error code might also be returned when the value of the CompletionPort parameter is not valid.

If an error occurs after some completions have been handled, the error notifications will be lost. An EFAULT error when copying out results can cause the situation.


  1. The following program fragment illustrates the use of the GetMultipleCompletionStatus subroutine to dequeue up to 10 completion packets within a 100-millisecond window.
    struct gmcs results[10];
    int n_results;
    HANDLE iocpfd;
    errno = 0;
    n_results = GetMultipleCompletionStatus(iocpfd, 10, 10, 100, results);