Tune the behavior of Sleep() and Waitxxx() to more closely resemble

Windows behavior.  The key is to yield in a Sleep and in any Wait that
times out.
This commit is contained in:
Jeremy White 2004-11-02 19:32:03 +00:00 committed by Alexandre Julliard
parent 49a5036c0a
commit 8099c2b9fd
1 changed files with 13 additions and 5 deletions

View File

@ -586,6 +586,12 @@ NTSTATUS NTDLL_wait_for_multiple_objects( UINT count, const HANDLE *handles, UIN
call_apcs( (flags & SELECT_ALERTABLE) != 0 );
if (flags & SELECT_ALERTABLE) break;
}
/* A test on Windows 2000 shows that Windows always yields during
a wait, but a wait that is hit by an event gets a priority
boost as well. This seems to model that behavior the closest. */
if (ret == WAIT_TIMEOUT) NtYieldExecution();
return ret;
}
@ -649,15 +655,15 @@ NTSTATUS WINAPI NtDelayExecution( BOOLEAN alertable, const LARGE_INTEGER *timeou
{
for (;;) select( 0, NULL, NULL, NULL, NULL );
}
else if (!timeout->QuadPart)
{
NtYieldExecution();
}
else
{
abs_time_t when;
NTDLL_get_server_timeout( &when, timeout );
/* Note that we yield after establishing the desired timeout */
NtYieldExecution();
for (;;)
{
struct timeval tv;
@ -668,7 +674,9 @@ NTSTATUS WINAPI NtDelayExecution( BOOLEAN alertable, const LARGE_INTEGER *timeou
tv.tv_usec += 1000000;
tv.tv_sec--;
}
if (tv.tv_sec < 0) tv.tv_sec = tv.tv_usec = 0;
/* if our yield already passed enough time, we're done */
if (tv.tv_sec < 0) break;
if (select( 0, NULL, NULL, NULL, &tv ) != -1) break;
}
}