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=4078... ============================================================================== --- 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 */