Commit in reactos/ntoskrnl/ob on MAIN
object.c+17-221.75 -> 1.76

- 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.

reactos/ntoskrnl/ob
object.c 1.75 -> 1.76
diff -u -r1.75 -r1.76
--- object.c	4 Mar 2004 00:07:02 -0000	1.75
+++ object.c	12 Mar 2004 00:28:13 -0000	1.76
@@ -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 @@
 
 
 static NTSTATUS
-ObpPerformRetentionChecksDpcLevel(IN POBJECT_HEADER ObjectHeader)
+ObpPerformRetentionChecksDpcLevel(IN POBJECT_HEADER ObjectHeader,
+				  IN LONG OldRefCount)
 {
   if (ObjectHeader->RefCount < 0)
     {
@@ -627,7 +628,7 @@
       KEBUGCHECK(0);
     }
 
-  if (ObjectHeader->RefCount == 0 &&
+  if (OldRefCount == 0 &&
       ObjectHeader->HandleCount == 0 &&
       ObjectHeader->Permanent == FALSE)
     {
@@ -696,18 +697,20 @@
 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 @@
 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]);
-    }
-
-  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);
+  /* 
+     Drop our reference and get the new count so we can tell if this was the
+     last reference.
+  */
+  NewRefCount = InterlockedDecrement(&Header->RefCount);
 
-  ObpPerformRetentionChecksDpcLevel(Header);
+  /* Check whether the object can now be deleted. */
+  ObpPerformRetentionChecksDpcLevel(Header, NewRefCount);
 }
 
 
CVSspam 0.2.8