From 55d274d1d23ea6ea2aa1eab828917ddb5d57e34e Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 30 Oct 2007 13:04:23 +0100 Subject: [PATCH] pdh: Fix a couple of race conditions in the thread handling. --- dlls/pdh/pdh_main.c | 44 ++++++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/dlls/pdh/pdh_main.c b/dlls/pdh/pdh_main.c index 49d0a33137e..37613eda879 100644 --- a/dlls/pdh/pdh_main.c +++ b/dlls/pdh/pdh_main.c @@ -380,17 +380,6 @@ PDH_STATUS WINAPI PdhCalculateCounterFromRawValue( PDH_HCOUNTER handle, DWORD fo return ret; } -/* caller must hold query lock */ -static void shutdown_query_thread( struct query *query ) -{ - SetEvent( query->stop ); - WaitForSingleObject( query->thread, INFINITE ); - - CloseHandle( query->stop ); - CloseHandle( query->thread ); - - query->thread = NULL; -} /*********************************************************************** * PdhCloseQuery (PDH.@) @@ -409,7 +398,20 @@ PDH_STATUS WINAPI PdhCloseQuery( PDH_HQUERY handle ) return PDH_INVALID_HANDLE; } - if (query->thread) shutdown_query_thread( query ); + if (query->thread) + { + HANDLE thread = query->thread; + SetEvent( query->stop ); + LeaveCriticalSection( &pdh_handle_cs ); + + WaitForSingleObject( thread, INFINITE ); + + EnterCriticalSection( &pdh_handle_cs ); + if (query->magic != PDH_MAGIC_QUERY) return ERROR_SUCCESS; + CloseHandle( query->stop ); + CloseHandle( query->thread ); + query->thread = NULL; + } LIST_FOR_EACH_SAFE( item, next, &query->counters ) { @@ -476,7 +478,6 @@ static DWORD CALLBACK collect_query_thread( void *arg ) DWORD interval = query->interval; HANDLE stop = query->stop; - SetEvent( stop ); for (;;) { if (WaitForSingleObject( stop, interval ) != WAIT_TIMEOUT) ExitThread( 0 ); @@ -520,8 +521,20 @@ PDH_STATUS WINAPI PdhCollectQueryDataEx( PDH_HQUERY handle, DWORD interval, HAND LeaveCriticalSection( &pdh_handle_cs ); return PDH_NO_DATA; } - if (query->thread) shutdown_query_thread( query ); - if (!(query->stop = CreateEventW( NULL, FALSE, FALSE, NULL ))) + if (query->thread) + { + HANDLE thread = query->thread; + SetEvent( query->stop ); + LeaveCriticalSection( &pdh_handle_cs ); + + WaitForSingleObject( thread, INFINITE ); + + EnterCriticalSection( &pdh_handle_cs ); + if (query->magic != PDH_MAGIC_QUERY) return PDH_INVALID_HANDLE; + CloseHandle( query->thread ); + query->thread = NULL; + } + else if (!(query->stop = CreateEventW( NULL, FALSE, FALSE, NULL ))) { ret = GetLastError(); LeaveCriticalSection( &pdh_handle_cs ); @@ -537,7 +550,6 @@ PDH_STATUS WINAPI PdhCollectQueryDataEx( PDH_HQUERY handle, DWORD interval, HAND LeaveCriticalSection( &pdh_handle_cs ); return ret; } - WaitForSingleObject( query->stop, INFINITE ); LeaveCriticalSection( &pdh_handle_cs ); return ERROR_SUCCESS;