Alexandre Julliard : pdh: Fix a couple of race conditions in the thread handling.

Alexandre Julliard julliard at winehq.org
Tue Oct 30 08:32:50 CDT 2007


Module: wine
Branch: master
Commit: 55d274d1d23ea6ea2aa1eab828917ddb5d57e34e
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=55d274d1d23ea6ea2aa1eab828917ddb5d57e34e

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue Oct 30 13:04:23 2007 +0100

pdh: Fix a couple of race conditions in the thread handling.

---

 dlls/pdh/pdh_main.c |   44 ++++++++++++++++++++++++++++----------------
 1 files changed, 28 insertions(+), 16 deletions(-)

diff --git a/dlls/pdh/pdh_main.c b/dlls/pdh/pdh_main.c
index 49d0a33..37613ed 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;




More information about the wine-cvs mailing list