mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-02 19:26:32 +00:00
- Use the return value from calling InterlockedDecrement on the reference
count when checking whether the object should be retained. This fixes a race whereby one thread decrements the value to one, another thread come in and decrements the value to zero and starts the delete, the first thread then comes back, does retention checks and finds the reference count is now zero and then bugchecks because the object is already being deleted. svn path=/trunk/; revision=8658
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/* $Id: object.c,v 1.75 2004/03/04 00:07:02 navaraf Exp $
|
||||
/* $Id: object.c,v 1.76 2004/03/12 00:28:13 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
@@ -611,7 +611,8 @@ ObpPerformRetentionChecksWorkRoutine (IN PVOID Parameter)
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
ObpPerformRetentionChecksDpcLevel(IN POBJECT_HEADER ObjectHeader)
|
||||
ObpPerformRetentionChecksDpcLevel(IN POBJECT_HEADER ObjectHeader,
|
||||
IN LONG OldRefCount)
|
||||
{
|
||||
if (ObjectHeader->RefCount < 0)
|
||||
{
|
||||
@@ -627,7 +628,7 @@ ObpPerformRetentionChecksDpcLevel(IN POBJECT_HEADER ObjectHeader)
|
||||
KEBUGCHECK(0);
|
||||
}
|
||||
|
||||
if (ObjectHeader->RefCount == 0 &&
|
||||
if (OldRefCount == 0 &&
|
||||
ObjectHeader->HandleCount == 0 &&
|
||||
ObjectHeader->Permanent == FALSE)
|
||||
{
|
||||
@@ -696,18 +697,20 @@ VOID FASTCALL
|
||||
ObfReferenceObject(IN PVOID Object)
|
||||
{
|
||||
POBJECT_HEADER Header;
|
||||
LONG NewRefCount;
|
||||
|
||||
assert(Object);
|
||||
|
||||
Header = BODY_TO_HEADER(Object);
|
||||
|
||||
/* No one should be referencing an object once we are deleting it. */
|
||||
if (Header->CloseInProcess)
|
||||
{
|
||||
KEBUGCHECK(0);
|
||||
}
|
||||
InterlockedIncrement(&Header->RefCount);
|
||||
|
||||
ObpPerformRetentionChecksDpcLevel(Header);
|
||||
NewRefCount = InterlockedIncrement(&Header->RefCount);
|
||||
ObpPerformRetentionChecksDpcLevel(Header, NewRefCount);
|
||||
}
|
||||
|
||||
|
||||
@@ -731,29 +734,21 @@ VOID FASTCALL
|
||||
ObfDereferenceObject(IN PVOID Object)
|
||||
{
|
||||
POBJECT_HEADER Header;
|
||||
extern POBJECT_TYPE PsProcessType;
|
||||
LONG NewRefCount;
|
||||
|
||||
assert(Object);
|
||||
|
||||
/* Extract the object header. */
|
||||
Header = BODY_TO_HEADER(Object);
|
||||
|
||||
if (Header->ObjectType == PsProcessType)
|
||||
{
|
||||
DPRINT("Deref p 0x%x with refcount %d type %x ",
|
||||
Object, Header->RefCount, PsProcessType);
|
||||
DPRINT("eip %x\n", ((PULONG)&Object)[-1]);
|
||||
}
|
||||
/*
|
||||
Drop our reference and get the new count so we can tell if this was the
|
||||
last reference.
|
||||
*/
|
||||
NewRefCount = InterlockedDecrement(&Header->RefCount);
|
||||
|
||||
if (Header->ObjectType == PsThreadType)
|
||||
{
|
||||
DPRINT("Deref t 0x%x with refcount %d type %x ",
|
||||
Object, Header->RefCount, PsThreadType);
|
||||
DPRINT("eip %x\n", ((PULONG)&Object)[-1]);
|
||||
}
|
||||
|
||||
InterlockedDecrement(&Header->RefCount);
|
||||
|
||||
ObpPerformRetentionChecksDpcLevel(Header);
|
||||
/* Check whether the object can now be deleted. */
|
||||
ObpPerformRetentionChecksDpcLevel(Header, NewRefCount);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user