Fix the behavior of GetOverlappedResult() and WSAGetOverlappedResult()
with non-manual-reset (auto-reset) events in the OVERLAPPED structures.
This commit is contained in:
parent
3e2887a929
commit
2b54cf91fc
|
@ -3266,22 +3266,38 @@ BOOL WINAPI WSAGetOverlappedResult ( SOCKET s, LPWSAOVERLAPPED lpOverlapped,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
if ( fWait )
|
||||||
r = WaitForSingleObjectEx (lpOverlapped->hEvent, fWait ? INFINITE : 0, TRUE);
|
{
|
||||||
} while (r == STATUS_USER_APC);
|
while ( WaitForSingleObjectEx (lpOverlapped->hEvent, INFINITE, TRUE) == STATUS_USER_APC );
|
||||||
|
}
|
||||||
|
else if ( lpOverlapped->Internal == STATUS_PENDING )
|
||||||
|
{
|
||||||
|
/* Wait in order to give APCs a chance to run. */
|
||||||
|
/* This is cheating, so we must set the event again in case of success -
|
||||||
|
it may be a non-manual reset event. */
|
||||||
|
while ( (r = WaitForSingleObjectEx (lpOverlapped->hEvent, 0, TRUE)) == STATUS_USER_APC );
|
||||||
|
if ( r == WAIT_OBJECT_0 )
|
||||||
|
NtSetEvent ( lpOverlapped->hEvent, NULL );
|
||||||
|
}
|
||||||
|
|
||||||
if ( lpcbTransfer )
|
if ( lpcbTransfer )
|
||||||
*lpcbTransfer = lpOverlapped->InternalHigh;
|
*lpcbTransfer = lpOverlapped->InternalHigh;
|
||||||
|
|
||||||
if ( lpdwFlags )
|
if ( lpdwFlags )
|
||||||
*lpdwFlags = lpOverlapped->Offset;
|
*lpdwFlags = lpOverlapped->Offset;
|
||||||
|
|
||||||
if ( r == WAIT_OBJECT_0 )
|
switch ( lpOverlapped->Internal )
|
||||||
|
{
|
||||||
|
case STATUS_SUCCESS:
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
case STATUS_PENDING:
|
||||||
WSASetLastError ( lpOverlapped->Internal == STATUS_PENDING ?
|
WSASetLastError ( WSA_IO_INCOMPLETE );
|
||||||
WSA_IO_INCOMPLETE : NtStatusToWSAError ( lpOverlapped->Internal ) );
|
if (fWait) ERR ("PENDING status after waiting!\n");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
default:
|
||||||
|
WSASetLastError ( NtStatusToWSAError ( lpOverlapped->Internal ));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
42
files/file.c
42
files/file.c
|
@ -1554,19 +1554,43 @@ BOOL WINAPI GetOverlappedResult(
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
if ( bWait )
|
||||||
TRACE("waiting on %p\n",lpOverlapped);
|
{
|
||||||
r = WaitForSingleObjectEx(lpOverlapped->hEvent, bWait?INFINITE:0, TRUE);
|
do {
|
||||||
TRACE("wait on %p returned %ld\n",lpOverlapped,r);
|
TRACE("waiting on %p\n",lpOverlapped);
|
||||||
} while (r==STATUS_USER_APC);
|
r = WaitForSingleObjectEx(lpOverlapped->hEvent, INFINITE, TRUE);
|
||||||
|
TRACE("wait on %p returned %ld\n",lpOverlapped,r);
|
||||||
|
} while (r==STATUS_USER_APC);
|
||||||
|
}
|
||||||
|
else if ( lpOverlapped->Internal == STATUS_PENDING )
|
||||||
|
{
|
||||||
|
/* Wait in order to give APCs a chance to run. */
|
||||||
|
/* This is cheating, so we must set the event again in case of success -
|
||||||
|
it may be a non-manual reset event. */
|
||||||
|
do {
|
||||||
|
TRACE("waiting on %p\n",lpOverlapped);
|
||||||
|
r = WaitForSingleObjectEx(lpOverlapped->hEvent, INFINITE, TRUE);
|
||||||
|
TRACE("wait on %p returned %ld\n",lpOverlapped,r);
|
||||||
|
} while (r==STATUS_USER_APC);
|
||||||
|
if ( r == WAIT_OBJECT_0 )
|
||||||
|
NtSetEvent ( lpOverlapped->hEvent, NULL );
|
||||||
|
}
|
||||||
|
|
||||||
if(lpTransferred)
|
if(lpTransferred)
|
||||||
*lpTransferred = lpOverlapped->InternalHigh;
|
*lpTransferred = lpOverlapped->InternalHigh;
|
||||||
|
|
||||||
SetLastError ( lpOverlapped->Internal == STATUS_PENDING ?
|
switch ( lpOverlapped->Internal )
|
||||||
ERROR_IO_INCOMPLETE : RtlNtStatusToDosError ( lpOverlapped->Internal ) );
|
{
|
||||||
|
case STATUS_SUCCESS:
|
||||||
return (r==WAIT_OBJECT_0);
|
return TRUE;
|
||||||
|
case STATUS_PENDING:
|
||||||
|
SetLastError ( ERROR_IO_INCOMPLETE );
|
||||||
|
if ( bWait ) ERR ("PENDING status after waiting!\n");
|
||||||
|
return FALSE;
|
||||||
|
default:
|
||||||
|
SetLastError ( RtlNtStatusToDosError ( lpOverlapped->Internal ) );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
|
Loading…
Reference in New Issue