[ros-diffs] [weiden] 40787: Make vectored exceptions thread-safe

weiden at svn.reactos.org weiden at svn.reactos.org
Mon May 4 20:06:16 CEST 2009


Author: weiden
Date: Mon May  4 22:06:15 2009
New Revision: 40787

URL: http://svn.reactos.org/svn/reactos?rev=40787&view=rev
Log:
Make vectored exceptions thread-safe

Modified:
    trunk/reactos/lib/rtl/vectoreh.c

Modified: trunk/reactos/lib/rtl/vectoreh.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/vectoreh.c?rev=40787&r1=40786&r2=40787&view=diff
==============================================================================
--- trunk/reactos/lib/rtl/vectoreh.c [iso-8859-1] (original)
+++ trunk/reactos/lib/rtl/vectoreh.c [iso-8859-1] Mon May  4 22:06:15 2009
@@ -15,11 +15,14 @@
 
 static RTL_CRITICAL_SECTION RtlpVectoredExceptionLock;
 static LIST_ENTRY RtlpVectoredExceptionHead;
+static volatile LONG RtlpVectoredExceptionsInstalled;
 
 typedef struct _RTL_VECTORED_EXCEPTION_HANDLER
 {
   LIST_ENTRY ListEntry;
   PVECTORED_EXCEPTION_HANDLER VectoredHandler;
+  ULONG Refs;
+  BOOLEAN Deleted;
 } RTL_VECTORED_EXCEPTION_HANDLER, *PRTL_VECTORED_EXCEPTION_HANDLER;
 
 /* FUNCTIONS ***************************************************************/
@@ -30,37 +33,70 @@
                                  IN PCONTEXT  Context)
 {
   PLIST_ENTRY CurrentEntry;
-  PRTL_VECTORED_EXCEPTION_HANDLER veh;
+  PRTL_VECTORED_EXCEPTION_HANDLER veh = NULL;
   PVECTORED_EXCEPTION_HANDLER VectoredHandler;
   EXCEPTION_POINTERS ExceptionInfo;
+  BOOLEAN Remove = FALSE;
+  BOOLEAN Ret = FALSE;
 
   ExceptionInfo.ExceptionRecord = ExceptionRecord;
   ExceptionInfo.ContextRecord = Context;
 
-  if(RtlpVectoredExceptionHead.Flink != &RtlpVectoredExceptionHead)
+  if(RtlpVectoredExceptionsInstalled)
   {
     RtlEnterCriticalSection(&RtlpVectoredExceptionLock);
-    for(CurrentEntry = RtlpVectoredExceptionHead.Flink;
-        CurrentEntry != &RtlpVectoredExceptionHead;
-        CurrentEntry = CurrentEntry->Flink)
+    CurrentEntry = RtlpVectoredExceptionHead.Flink;
+    while (CurrentEntry != &RtlpVectoredExceptionHead)
     {
       veh = CONTAINING_RECORD(CurrentEntry,
                               RTL_VECTORED_EXCEPTION_HANDLER,
                               ListEntry);
+      veh->Refs++;
+      RtlLeaveCriticalSection(&RtlpVectoredExceptionLock);
+      
       VectoredHandler = RtlDecodePointer(veh->VectoredHandler);
-      RtlLeaveCriticalSection(&RtlpVectoredExceptionLock);
-
       if(VectoredHandler(&ExceptionInfo) == EXCEPTION_CONTINUE_EXECUTION)
       {
-        return TRUE;
+        RtlEnterCriticalSection(&RtlpVectoredExceptionLock);
+        if (--veh->Refs == 0)
+        {
+          RemoveEntryList (&veh->ListEntry);
+          InterlockedDecrement (&RtlpVectoredExceptionsInstalled);
+          Remove = TRUE;
+        }
+        Ret = TRUE;
+        break;
       }
 
       RtlEnterCriticalSection(&RtlpVectoredExceptionLock);
+      
+      if (--veh->Refs == 0)
+      {
+        CurrentEntry = veh->ListEntry.Flink;
+        RemoveEntryList (&veh->ListEntry);
+        InterlockedDecrement (&RtlpVectoredExceptionsInstalled);
+        RtlLeaveCriticalSection(&RtlpVectoredExceptionLock);
+        
+        RtlFreeHeap(RtlGetProcessHeap(),
+                    0,
+                    veh);
+        RtlEnterCriticalSection(&RtlpVectoredExceptionLock);
+      }
+      else
+        CurrentEntry = CurrentEntry->Flink;
     }
+    
     RtlLeaveCriticalSection(&RtlpVectoredExceptionLock);
   }
+  
+  if (Remove)
+  {
+    RtlFreeHeap(RtlGetProcessHeap(),
+                0,
+                veh);
+  }
 
-  return FALSE;
+  return Ret;
 }
 
 VOID
@@ -68,6 +104,7 @@
 {
   InitializeListHead(&RtlpVectoredExceptionHead);
   RtlInitializeCriticalSection(&RtlpVectoredExceptionLock);
+  RtlpVectoredExceptionsInstalled = 0;
 }
 
 
@@ -86,6 +123,8 @@
   if(veh != NULL)
   {
     veh->VectoredHandler = RtlEncodePointer(VectoredHandler);
+    veh->Refs = 1;
+    veh->Deleted = FALSE;
     RtlEnterCriticalSection(&RtlpVectoredExceptionLock);
     if(FirstHandler != 0)
     {
@@ -97,6 +136,7 @@
       InsertTailList(&RtlpVectoredExceptionHead,
                      &veh->ListEntry);
     }
+    InterlockedIncrement (&RtlpVectoredExceptionsInstalled);
     RtlLeaveCriticalSection(&RtlpVectoredExceptionLock);
   }
 
@@ -112,7 +152,8 @@
 {
   PLIST_ENTRY CurrentEntry;
   PRTL_VECTORED_EXCEPTION_HANDLER veh = NULL;
-  ULONG Removed = FALSE;
+  BOOLEAN Remove = FALSE;
+  ULONG Ret = FALSE;
 
   RtlEnterCriticalSection(&RtlpVectoredExceptionLock);
   for(CurrentEntry = RtlpVectoredExceptionHead.Flink;
@@ -124,21 +165,29 @@
                             ListEntry);
     if(veh == VectoredHandlerHandle)
     {
-      RemoveEntryList(&veh->ListEntry);
-      Removed = TRUE;
-      break;
+      if (!veh->Deleted)
+      {
+        if (--veh->Refs == 0)
+        {
+          RemoveEntryList (&veh->ListEntry);
+          Remove = TRUE;
+        }
+        veh->Deleted = TRUE;
+        Ret = TRUE;
+        break;
+      }
     }
   }
   RtlLeaveCriticalSection(&RtlpVectoredExceptionLock);
 
-  if(Removed)
+  if(Remove)
   {
     RtlFreeHeap(RtlGetProcessHeap(),
                 0,
                 veh);
   }
 
-  return Removed;
+  return Ret;
 }
 
 /* EOF */



More information about the Ros-diffs mailing list