reactos/ntoskrnl/ob
diff -u -r1.76 -r1.77
--- object.c 12 Mar 2004 00:28:13 -0000 1.76
+++ object.c 12 Mar 2004 00:46:35 -0000 1.77
@@ -1,4 +1,4 @@
-/* $Id: object.c,v 1.76 2004/03/12 00:28:13 dwelch Exp $
+/* $Id: object.c,v 1.77 2004/03/12 00:46:35 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@@ -565,7 +565,7 @@
static NTSTATUS
-ObpPerformRetentionChecks(POBJECT_HEADER Header)
+ObpDeleteObject(POBJECT_HEADER Header)
{
DPRINT("ObPerformRetentionChecks(Header %p)\n", Header);
if (KeGetCurrentIrql() != PASSIVE_LEVEL)
@@ -594,7 +594,7 @@
VOID STDCALL
-ObpPerformRetentionChecksWorkRoutine (IN PVOID Parameter)
+ObpDeleteObjectWorkRoutine (IN PVOID Parameter)
{
PRETENTION_CHECK_PARAMS Params = (PRETENTION_CHECK_PARAMS)Parameter;
/* ULONG Tag; */ /* See below */
@@ -604,73 +604,71 @@
/* Turn this on when we have ExFreePoolWithTag
Tag = Params->ObjectHeader->ObjectType->Tag; */
- ObpPerformRetentionChecks(Params->ObjectHeader);
+ ObpDeleteObject(Params->ObjectHeader);
ExFreePool(Params);
/* ExFreePoolWithTag(Params, Tag); */
}
-static NTSTATUS
-ObpPerformRetentionChecksDpcLevel(IN POBJECT_HEADER ObjectHeader,
- IN LONG OldRefCount)
+STATIC NTSTATUS
+ObpDeleteObjectDpcLevel(IN POBJECT_HEADER ObjectHeader,
+ IN LONG OldRefCount)
{
if (ObjectHeader->RefCount < 0)
{
CPRINT("Object %p/%p has invalid reference count (%d)\n",
- ObjectHeader, HEADER_TO_BODY(ObjectHeader), ObjectHeader->RefCount);
+ ObjectHeader, HEADER_TO_BODY(ObjectHeader),
+ ObjectHeader->RefCount);
KEBUGCHECK(0);
}
if (ObjectHeader->HandleCount < 0)
{
CPRINT("Object %p/%p has invalid handle count (%d)\n",
- ObjectHeader, HEADER_TO_BODY(ObjectHeader), ObjectHeader->HandleCount);
+ ObjectHeader, HEADER_TO_BODY(ObjectHeader),
+ ObjectHeader->HandleCount);
KEBUGCHECK(0);
}
- if (OldRefCount == 0 &&
- ObjectHeader->HandleCount == 0 &&
- ObjectHeader->Permanent == FALSE)
+ if (ObjectHeader->CloseInProcess)
{
- if (ObjectHeader->CloseInProcess)
- {
- KEBUGCHECK(0);
- return STATUS_UNSUCCESSFUL;
- }
- ObjectHeader->CloseInProcess = TRUE;
-
- switch (KeGetCurrentIrql ())
- {
- case PASSIVE_LEVEL:
- return ObpPerformRetentionChecks (ObjectHeader);
-
- case APC_LEVEL:
- case DISPATCH_LEVEL:
- {
- PRETENTION_CHECK_PARAMS Params;
-
- /*
- * Can we get rid of this NonPagedPoolMustSucceed call and still be a
- * 'must succeed' function? I don't like to bugcheck on no memory!
- */
- Params = (PRETENTION_CHECK_PARAMS)ExAllocatePoolWithTag(NonPagedPoolMustSucceed,
- sizeof(RETENTION_CHECK_PARAMS),
- ObjectHeader->ObjectType->Tag);
- Params->ObjectHeader = ObjectHeader;
- ExInitializeWorkItem(&Params->WorkItem,
- ObpPerformRetentionChecksWorkRoutine,
- (PVOID)Params);
- ExQueueWorkItem(&Params->WorkItem,
- CriticalWorkQueue);
- }
- return STATUS_PENDING;
-
- default:
- DPRINT("ObpPerformRetentionChecksDpcLevel called at unsupported IRQL %u!\n",
- KeGetCurrentIrql());
- KEBUGCHECK(0);
- return STATUS_UNSUCCESSFUL;
- }
+ KEBUGCHECK(0);
+ return STATUS_UNSUCCESSFUL;
+ }
+ ObjectHeader->CloseInProcess = TRUE;
+
+ switch (KeGetCurrentIrql ())
+ {
+ case PASSIVE_LEVEL:
+ return ObpDeleteObject (ObjectHeader);
+
+ case APC_LEVEL:
+ case DISPATCH_LEVEL:
+ {
+ PRETENTION_CHECK_PARAMS Params;
+
+ /*
+ We use must succeed pool here because if the allocation fails
+ then we leak memory.
+ */
+ Params = (PRETENTION_CHECK_PARAMS)
+ ExAllocatePoolWithTag(NonPagedPoolMustSucceed,
+ sizeof(RETENTION_CHECK_PARAMS),
+ ObjectHeader->ObjectType->Tag);
+ Params->ObjectHeader = ObjectHeader;
+ ExInitializeWorkItem(&Params->WorkItem,
+ ObpDeleteObjectWorkRoutine,
+ (PVOID)Params);
+ ExQueueWorkItem(&Params->WorkItem,
+ CriticalWorkQueue);
+ }
+ return STATUS_PENDING;
+
+ default:
+ DPRINT("ObpPerformRetentionChecksDpcLevel called at unsupported "
+ "IRQL %u!\n", KeGetCurrentIrql());
+ KEBUGCHECK(0);
+ return STATUS_UNSUCCESSFUL;
}
return STATUS_SUCCESS;
@@ -697,7 +695,6 @@
ObfReferenceObject(IN PVOID Object)
{
POBJECT_HEADER Header;
- LONG NewRefCount;
assert(Object);
@@ -709,8 +706,7 @@
KEBUGCHECK(0);
}
- NewRefCount = InterlockedIncrement(&Header->RefCount);
- ObpPerformRetentionChecksDpcLevel(Header, NewRefCount);
+ (VOID)InterlockedIncrement(&Header->RefCount);
}
@@ -735,20 +731,30 @@
{
POBJECT_HEADER Header;
LONG NewRefCount;
+ BOOL Permanent;
+ ULONG HandleCount;
assert(Object);
/* Extract the object header. */
Header = BODY_TO_HEADER(Object);
+ Permanent = Header->Permanent;
+ HandleCount = Header->HandleCount;
/*
Drop our reference and get the new count so we can tell if this was the
last reference.
*/
NewRefCount = InterlockedDecrement(&Header->RefCount);
+ assert(NewRefCount >= 0);
/* Check whether the object can now be deleted. */
- ObpPerformRetentionChecksDpcLevel(Header, NewRefCount);
+ if (NewRefCount == 0 &&
+ HandleCount == 0 &&
+ !Permanent)
+ {
+ ObpDeleteObjectDpcLevel(Header, NewRefCount);
+ }
}