while ( 1 )
{
// scavenge sockets
for ( i=0; i<OVERLAPPEDIONUM; i++ )
{
/*
if (pObject->m_IODATA[i].acceptSocket==NULL)
continue;*/
if ( pObject->m_IODATA[i].opState == stAccepting )
{
// stAccepting means AcceptEx() called, but no completion yet
// determine if the socket is connected
seconds = 0;
len = sizeof seconds;
if ( 0 == getsockopt( pObject->m_IODATA[i].acceptSocket, SOL_SOCKET,
SO_CONNECT_TIME, (char *) &seconds, &len ) )
{
if ( seconds != -1 && seconds * 1000 > timeout * 2 )
{
// closesocket() here causes an immediate IOCP notification
// with an error indication; that will cause our worker thread
// to call DoClose(). The state of the listener socket will
// determine whether the socket will be reopened to accept
// another connection, or whether it is left for dead.
CancelIo((HANDLE)pObject->m_IODATA[i].acceptSocket);
closesocket( pObject->m_IODATA[i].acceptSocket );
}
}
}
else if ( pObject->m_IODATA[i].opState == stReading )
{
// stAccepting means AcceptEx() called, but no completion yet
// determine if the socket is connected
seconds = 0;
len = sizeof seconds;
if ( 0 == getsockopt( pObject->m_IODATA[i].acceptSocket, SOL_SOCKET,
SO_CONNECT_TIME, (char *) &seconds, &len ) )
{
if ( seconds != -1 && seconds * 1000 > timeout * 600)
{
// closesocket() here causes an immediate IOCP notification
// with an error indication; that will cause our worker thread
// to call DoClose(). The state of the listener socket will
// determine whether the socket will be reopened to accept
// another connection, or whether it is left for dead.
CancelIo((HANDLE)pObject->m_IODATA[i].acceptSocket);
closesocket( pObject->m_IODATA[i].acceptSocket );
}
}
}
else if ( pObject->m_IODATA[i].opState == stWriting )
{
// stAccepting means AcceptEx() called, but no completion yet
// determine if the socket is connected
seconds = 0;
len = sizeof seconds;
if ( 0 == getsockopt( pObject->m_IODATA[i].acceptSocket, SOL_SOCKET,
SO_CONNECT_TIME, (char *) &seconds, &len ) )
{
if ( seconds != -1 && seconds * 1000 > timeout * 600)
{
// closesocket() here causes an immediate IOCP notification
// with an error indication; that will cause our worker thread
// to call DoClose(). The state of the listener socket will
// determine whether the socket will be reopened to accept
// another connection, or whether it is left for dead.
CancelIo((HANDLE)pObject->m_IODATA[i].acceptSocket);
closesocket( pObject->m_IODATA[i].acceptSocket );
}
}
}
}
// pause until next run due
st = WaitForSingleObject( g_suicideEvent,100);
if ( st != WAIT_TIMEOUT )
break;
}
return 0;
}
Members
Internal
Reserved for internal use. The Internal member is used internally by the entity that implements overlapped I/O. For service providers that create sockets as installable file system (IFS) handles, this parameter is used by the underlying operating system. Other service providers (non-IFS providers) are free to use this parameter as necessary.
InternalHigh
Reserved. Used internally by the entity that implements overlapped I/O. For service providers that create sockets as IFS handles, this parameter is used by the underlying operating system. NonIFS providers are free to use this parameter as necessary.
Offset
Reserved for use by service providers.
OffsetHigh
Reserved for use by service providers.
hEvent
If an overlapped I/O operation is issued without an I/O completion routine (lpCompletionRoutine is null), then this parameter should either contain a valid handle to a WSAEVENT object or be null. If lpCompletionRoutine is non-null then applications are free to use this parameter as necessary.