mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 22:23:01 +00:00
Make vectored exceptions thread-safe
svn path=/trunk/; revision=40787
This commit is contained in:
parent
007909b14a
commit
2e9b52a3a5
1 changed files with 64 additions and 15 deletions
|
@ -15,11 +15,14 @@
|
||||||
|
|
||||||
static RTL_CRITICAL_SECTION RtlpVectoredExceptionLock;
|
static RTL_CRITICAL_SECTION RtlpVectoredExceptionLock;
|
||||||
static LIST_ENTRY RtlpVectoredExceptionHead;
|
static LIST_ENTRY RtlpVectoredExceptionHead;
|
||||||
|
static volatile LONG RtlpVectoredExceptionsInstalled;
|
||||||
|
|
||||||
typedef struct _RTL_VECTORED_EXCEPTION_HANDLER
|
typedef struct _RTL_VECTORED_EXCEPTION_HANDLER
|
||||||
{
|
{
|
||||||
LIST_ENTRY ListEntry;
|
LIST_ENTRY ListEntry;
|
||||||
PVECTORED_EXCEPTION_HANDLER VectoredHandler;
|
PVECTORED_EXCEPTION_HANDLER VectoredHandler;
|
||||||
|
ULONG Refs;
|
||||||
|
BOOLEAN Deleted;
|
||||||
} RTL_VECTORED_EXCEPTION_HANDLER, *PRTL_VECTORED_EXCEPTION_HANDLER;
|
} RTL_VECTORED_EXCEPTION_HANDLER, *PRTL_VECTORED_EXCEPTION_HANDLER;
|
||||||
|
|
||||||
/* FUNCTIONS ***************************************************************/
|
/* FUNCTIONS ***************************************************************/
|
||||||
|
@ -30,37 +33,70 @@ RtlCallVectoredExceptionHandlers(IN PEXCEPTION_RECORD ExceptionRecord,
|
||||||
IN PCONTEXT Context)
|
IN PCONTEXT Context)
|
||||||
{
|
{
|
||||||
PLIST_ENTRY CurrentEntry;
|
PLIST_ENTRY CurrentEntry;
|
||||||
PRTL_VECTORED_EXCEPTION_HANDLER veh;
|
PRTL_VECTORED_EXCEPTION_HANDLER veh = NULL;
|
||||||
PVECTORED_EXCEPTION_HANDLER VectoredHandler;
|
PVECTORED_EXCEPTION_HANDLER VectoredHandler;
|
||||||
EXCEPTION_POINTERS ExceptionInfo;
|
EXCEPTION_POINTERS ExceptionInfo;
|
||||||
|
BOOLEAN Remove = FALSE;
|
||||||
|
BOOLEAN Ret = FALSE;
|
||||||
|
|
||||||
ExceptionInfo.ExceptionRecord = ExceptionRecord;
|
ExceptionInfo.ExceptionRecord = ExceptionRecord;
|
||||||
ExceptionInfo.ContextRecord = Context;
|
ExceptionInfo.ContextRecord = Context;
|
||||||
|
|
||||||
if(RtlpVectoredExceptionHead.Flink != &RtlpVectoredExceptionHead)
|
if(RtlpVectoredExceptionsInstalled)
|
||||||
{
|
{
|
||||||
RtlEnterCriticalSection(&RtlpVectoredExceptionLock);
|
RtlEnterCriticalSection(&RtlpVectoredExceptionLock);
|
||||||
for(CurrentEntry = RtlpVectoredExceptionHead.Flink;
|
CurrentEntry = RtlpVectoredExceptionHead.Flink;
|
||||||
CurrentEntry != &RtlpVectoredExceptionHead;
|
while (CurrentEntry != &RtlpVectoredExceptionHead)
|
||||||
CurrentEntry = CurrentEntry->Flink)
|
|
||||||
{
|
{
|
||||||
veh = CONTAINING_RECORD(CurrentEntry,
|
veh = CONTAINING_RECORD(CurrentEntry,
|
||||||
RTL_VECTORED_EXCEPTION_HANDLER,
|
RTL_VECTORED_EXCEPTION_HANDLER,
|
||||||
ListEntry);
|
ListEntry);
|
||||||
VectoredHandler = RtlDecodePointer(veh->VectoredHandler);
|
veh->Refs++;
|
||||||
RtlLeaveCriticalSection(&RtlpVectoredExceptionLock);
|
RtlLeaveCriticalSection(&RtlpVectoredExceptionLock);
|
||||||
|
|
||||||
|
VectoredHandler = RtlDecodePointer(veh->VectoredHandler);
|
||||||
if(VectoredHandler(&ExceptionInfo) == EXCEPTION_CONTINUE_EXECUTION)
|
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);
|
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);
|
RtlLeaveCriticalSection(&RtlpVectoredExceptionLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
return FALSE;
|
if (Remove)
|
||||||
|
{
|
||||||
|
RtlFreeHeap(RtlGetProcessHeap(),
|
||||||
|
0,
|
||||||
|
veh);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -68,6 +104,7 @@ RtlpInitializeVectoredExceptionHandling(VOID)
|
||||||
{
|
{
|
||||||
InitializeListHead(&RtlpVectoredExceptionHead);
|
InitializeListHead(&RtlpVectoredExceptionHead);
|
||||||
RtlInitializeCriticalSection(&RtlpVectoredExceptionLock);
|
RtlInitializeCriticalSection(&RtlpVectoredExceptionLock);
|
||||||
|
RtlpVectoredExceptionsInstalled = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -86,6 +123,8 @@ RtlAddVectoredExceptionHandler(IN ULONG FirstHandler,
|
||||||
if(veh != NULL)
|
if(veh != NULL)
|
||||||
{
|
{
|
||||||
veh->VectoredHandler = RtlEncodePointer(VectoredHandler);
|
veh->VectoredHandler = RtlEncodePointer(VectoredHandler);
|
||||||
|
veh->Refs = 1;
|
||||||
|
veh->Deleted = FALSE;
|
||||||
RtlEnterCriticalSection(&RtlpVectoredExceptionLock);
|
RtlEnterCriticalSection(&RtlpVectoredExceptionLock);
|
||||||
if(FirstHandler != 0)
|
if(FirstHandler != 0)
|
||||||
{
|
{
|
||||||
|
@ -97,6 +136,7 @@ RtlAddVectoredExceptionHandler(IN ULONG FirstHandler,
|
||||||
InsertTailList(&RtlpVectoredExceptionHead,
|
InsertTailList(&RtlpVectoredExceptionHead,
|
||||||
&veh->ListEntry);
|
&veh->ListEntry);
|
||||||
}
|
}
|
||||||
|
InterlockedIncrement (&RtlpVectoredExceptionsInstalled);
|
||||||
RtlLeaveCriticalSection(&RtlpVectoredExceptionLock);
|
RtlLeaveCriticalSection(&RtlpVectoredExceptionLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +152,8 @@ RtlRemoveVectoredExceptionHandler(IN PVOID VectoredHandlerHandle)
|
||||||
{
|
{
|
||||||
PLIST_ENTRY CurrentEntry;
|
PLIST_ENTRY CurrentEntry;
|
||||||
PRTL_VECTORED_EXCEPTION_HANDLER veh = NULL;
|
PRTL_VECTORED_EXCEPTION_HANDLER veh = NULL;
|
||||||
ULONG Removed = FALSE;
|
BOOLEAN Remove = FALSE;
|
||||||
|
ULONG Ret = FALSE;
|
||||||
|
|
||||||
RtlEnterCriticalSection(&RtlpVectoredExceptionLock);
|
RtlEnterCriticalSection(&RtlpVectoredExceptionLock);
|
||||||
for(CurrentEntry = RtlpVectoredExceptionHead.Flink;
|
for(CurrentEntry = RtlpVectoredExceptionHead.Flink;
|
||||||
|
@ -124,21 +165,29 @@ RtlRemoveVectoredExceptionHandler(IN PVOID VectoredHandlerHandle)
|
||||||
ListEntry);
|
ListEntry);
|
||||||
if(veh == VectoredHandlerHandle)
|
if(veh == VectoredHandlerHandle)
|
||||||
{
|
{
|
||||||
RemoveEntryList(&veh->ListEntry);
|
if (!veh->Deleted)
|
||||||
Removed = TRUE;
|
{
|
||||||
break;
|
if (--veh->Refs == 0)
|
||||||
|
{
|
||||||
|
RemoveEntryList (&veh->ListEntry);
|
||||||
|
Remove = TRUE;
|
||||||
|
}
|
||||||
|
veh->Deleted = TRUE;
|
||||||
|
Ret = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RtlLeaveCriticalSection(&RtlpVectoredExceptionLock);
|
RtlLeaveCriticalSection(&RtlpVectoredExceptionLock);
|
||||||
|
|
||||||
if(Removed)
|
if(Remove)
|
||||||
{
|
{
|
||||||
RtlFreeHeap(RtlGetProcessHeap(),
|
RtlFreeHeap(RtlGetProcessHeap(),
|
||||||
0,
|
0,
|
||||||
veh);
|
veh);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Removed;
|
return Ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue