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=407…
==============================================================================
--- 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 */