/* * Win32 process and thread synchronisation * * Copyright 1997 Alexandre Julliard * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "winbase.h" #include "winternl.h" #include "../kernel/kernel_private.h" /* FIXME: to be changed when moving file to dlls/kernel */ /*********************************************************************** * Sleep (KERNEL32.@) */ VOID WINAPI Sleep( DWORD timeout ) { SleepEx( timeout, FALSE ); } /****************************************************************************** * SleepEx (KERNEL32.@) */ DWORD WINAPI SleepEx( DWORD timeout, BOOL alertable ) { NTSTATUS status; if (timeout == INFINITE) status = NtDelayExecution( alertable, NULL ); else { LARGE_INTEGER time; time.QuadPart = timeout * (ULONGLONG)10000; time.QuadPart = -time.QuadPart; status = NtDelayExecution( alertable, &time ); } if (status != STATUS_USER_APC) status = STATUS_SUCCESS; return status; } /*********************************************************************** * WaitForSingleObject (KERNEL32.@) */ DWORD WINAPI WaitForSingleObject( HANDLE handle, DWORD timeout ) { return WaitForMultipleObjectsEx( 1, &handle, FALSE, timeout, FALSE ); } /*********************************************************************** * WaitForSingleObjectEx (KERNEL32.@) */ DWORD WINAPI WaitForSingleObjectEx( HANDLE handle, DWORD timeout, BOOL alertable ) { return WaitForMultipleObjectsEx( 1, &handle, FALSE, timeout, alertable ); } /*********************************************************************** * WaitForMultipleObjects (KERNEL32.@) */ DWORD WINAPI WaitForMultipleObjects( DWORD count, const HANDLE *handles, BOOL wait_all, DWORD timeout ) { return WaitForMultipleObjectsEx( count, handles, wait_all, timeout, FALSE ); } /*********************************************************************** * WaitForMultipleObjectsEx (KERNEL32.@) */ DWORD WINAPI WaitForMultipleObjectsEx( DWORD count, const HANDLE *handles, BOOL wait_all, DWORD timeout, BOOL alertable ) { NTSTATUS status; HANDLE hloc[MAXIMUM_WAIT_OBJECTS]; int i; if (count >= MAXIMUM_WAIT_OBJECTS) { SetLastError(ERROR_INVALID_PARAMETER); return WAIT_FAILED; } for (i = 0; i < count; i++) { if ((handles[i] == (HANDLE)STD_INPUT_HANDLE) || (handles[i] == (HANDLE)STD_OUTPUT_HANDLE) || (handles[i] == (HANDLE)STD_ERROR_HANDLE)) hloc[i] = GetStdHandle( (DWORD)handles[i] ); else hloc[i] = handles[i]; /* yes, even screen buffer console handles are waitable, and are * handled as a handle to the console itself !! */ if (is_console_handle(hloc[i])) { if (!VerifyConsoleIoHandle(hloc[i])) { return FALSE; } hloc[i] = GetConsoleInputWaitHandle(); } } if (timeout == INFINITE) { status = NtWaitForMultipleObjects( count, hloc, wait_all, alertable, NULL ); } else { LARGE_INTEGER time; time.QuadPart = timeout * (ULONGLONG)10000; time.QuadPart = -time.QuadPart; status = NtWaitForMultipleObjects( count, hloc, wait_all, alertable, &time ); } if (HIWORD(status)) /* is it an error code? */ { SetLastError( RtlNtStatusToDosError(status) ); status = WAIT_FAILED; } return status; } /*********************************************************************** * WaitForSingleObject (KERNEL.460) */ DWORD WINAPI WaitForSingleObject16( HANDLE handle, DWORD timeout ) { DWORD retval, mutex_count; ReleaseThunkLock( &mutex_count ); retval = WaitForSingleObject( handle, timeout ); RestoreThunkLock( mutex_count ); return retval; } /*********************************************************************** * WaitForMultipleObjects (KERNEL.461) */ DWORD WINAPI WaitForMultipleObjects16( DWORD count, const HANDLE *handles, BOOL wait_all, DWORD timeout ) { DWORD retval, mutex_count; ReleaseThunkLock( &mutex_count ); retval = WaitForMultipleObjectsEx( count, handles, wait_all, timeout, FALSE ); RestoreThunkLock( mutex_count ); return retval; } /*********************************************************************** * WaitForMultipleObjectsEx (KERNEL.495) */ DWORD WINAPI WaitForMultipleObjectsEx16( DWORD count, const HANDLE *handles, BOOL wait_all, DWORD timeout, BOOL alertable ) { DWORD retval, mutex_count; ReleaseThunkLock( &mutex_count ); retval = WaitForMultipleObjectsEx( count, handles, wait_all, timeout, alertable ); RestoreThunkLock( mutex_count ); return retval; }