Archived

This topic is now archived and is closed to further replies.

kuphryn

I/O Completion Port and Queue Status :: Winsock

Recommended Posts

Hi. I am in the process of implementing a IOCP on a Windows program. The program works as designs using WSAAsyncSelect I/O. Under IOCP, for some reason the call to function GetQueuedCompletionStatus(...) returns immediately even when I specify INFINITE wait. Thus, the cpu usage is aways at 100%. This occurs during program initialization as I want the program to create a completion port on startup. Again, the creating of the completion port does not run an error. The creation of the worker thread to handle completion events and where GetQueuedCompletionStatus(...) resides does not run an error. However, for some reason, GetQueueCompletionStatus(...) returns immediately even with the INFINITE parameter. This occurs while the completion port is empty, or there are no sockets associated with it yet. How is that possible? And each time it returns, the byte transfer is always 0. Please post if you have any suggestion as to where to begin debugging. Thanks, Kuphryn

Share this post


Link to post
Share on other sites
Did you associate the socket with the completion port?

You need to create the completion port calling:


    

// create the completion port

HANDLE completionPort =
CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 0);



Next, after you create your socket (make sure you use the WSA_FLAG_OVERLAPPED in the call to WSASocket), associate the socket with the completion port:


       
// create the socket...etc

SOCKET netSocket;

// ...


// associate the socket with the completion port

HANDLE result = CreateIoCompletionPort(netSocket,
completionPort,
0,
0);



Now, when you post an operation using WSASend/WSARecv, you basically just fill in the lpOverlapped and lpCompletionRoutine parameters and away you go. Take one of your "pooled" threads and call GetQueuedCompletionStatus:


  
OVERLAPPED* overlapped = 0;
ULONG_PTR key = 0;
DWORD bytesTransferred = 0;

BOOL result = GetQueuedCompletionStatus(completionPort,
bytesTransferred,
key,
&overlapped,
INFINITE);

if(!result)
{
DWORD error = GetLastError();

if(overlapped != NULL)
{
// the I/O operation FAILED.

// handle the error...

}
else
{
if(error == WAIT_TIMEOUT)
{
// timeout expired while waiting for a completion packet

// handle the timeout...

}
else
{
// the call to GetQueuedCompletionStatus failed internally!

// handle the error...

}
}
else
{
// I/O operation completed successfully!

// handle the I/O completion...

}


That should do it. Hopefully this helps you out a bit.

Regards.



[edited by - Digitalfiend on November 3, 2002 3:06:52 PM]

Share this post


Link to post
Share on other sites