From c61a3955d5c4978e792dc160f7024a08caa99a4b Mon Sep 17 00:00:00 2001 From: David Welch Date: Fri, 12 Mar 2004 00:28:13 +0000 Subject: [PATCH] - 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 --- reactos/ntoskrnl/ob/object.c | 39 ++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/reactos/ntoskrnl/ob/object.c b/reactos/ntoskrnl/ob/object.c index efc49b0751d..edbeabff4db 100644 --- a/reactos/ntoskrnl/ob/object.c +++ b/reactos/ntoskrnl/ob/object.c @@ -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); }