implemented sweeping of handle tables
authorThomas Bluemel <thomas@reactsoft.com>
Wed, 7 Dec 2005 17:06:48 +0000 (17:06 +0000)
committerThomas Bluemel <thomas@reactsoft.com>
Wed, 7 Dec 2005 17:06:48 +0000 (17:06 +0000)
svn path=/trunk/; revision=19951

reactos/ntoskrnl/ex/handle.c
reactos/ntoskrnl/include/internal/ex.h
reactos/ntoskrnl/ob/handle.c
reactos/ntoskrnl/rtl/libsupp.c

index 21fe5f6..71ec925 100644 (file)
@@ -11,7 +11,6 @@
  *
  *  - the last entry of a subhandle list should be reserved for auditing
  *
- *  ExSweepHandleTable (???)
  *  ExReferenceHandleDebugInfo
  *  ExSnapShotHandleTables
  *  ExpMoveFreeHandles (???)
@@ -163,63 +162,12 @@ ExCreateHandleTable(IN PEPROCESS QuotaProcess  OPTIONAL)
   return HandleTable;
 }
 
-static BOOLEAN
-ExLockHandleTableEntryNoDestructionCheck(IN PHANDLE_TABLE HandleTable,
-                                         IN PHANDLE_TABLE_ENTRY Entry)
-{
-  ULONG_PTR Current, New;
-
-  PAGED_CODE();
-
-  DPRINT("Entering handle table entry 0x%p lock...\n", Entry);
-
-  ASSERT(HandleTable);
-  ASSERT(Entry);
-
-  for(;;)
-  {
-    Current = (volatile ULONG_PTR)Entry->u1.Object;
-
-    if(!Current)
-    {
-      DPRINT("Attempted to lock empty handle table entry 0x%p or handle table shut down\n", Entry);
-      break;
-    }
-
-    if(!(Current & EX_HANDLE_ENTRY_LOCKED))
-    {
-      New = Current | EX_HANDLE_ENTRY_LOCKED;
-      if(InterlockedCompareExchangePointer(&Entry->u1.Object,
-                                           (PVOID)New,
-                                           (PVOID)Current) == (PVOID)Current)
-      {
-        DPRINT("SUCCESS handle table 0x%p entry 0x%p lock\n", HandleTable, Entry);
-        /* we acquired the lock */
-        return TRUE;
-      }
-    }
-
-    /* wait about 5ms at maximum so we don't wait forever in unfortunate
-       co-incidences where releasing the lock in another thread happens right
-       before we're waiting on the contention event to get pulsed, which might
-       never happen again... */
-    KeWaitForSingleObject(&HandleTable->HandleContentionEvent,
-                          Executive,
-                          KernelMode,
-                          FALSE,
-                          &ExpHandleShortWait);
-  }
-
-  return FALSE;
-}
-
 VOID
-ExDestroyHandleTable(IN PHANDLE_TABLE HandleTable,
-                     IN PEX_DESTROY_HANDLE_CALLBACK DestroyHandleCallback  OPTIONAL,
-                     IN PVOID Context  OPTIONAL)
+ExSweepHandleTable(IN PHANDLE_TABLE HandleTable,
+                   IN PEX_SWEEP_HANDLE_CALLBACK SweepHandleCallback  OPTIONAL,
+                   IN PVOID Context  OPTIONAL)
 {
   PHANDLE_TABLE_ENTRY **tlp, **lasttlp, *mlp, *lastmlp;
-  PEPROCESS QuotaProcess;
 
   PAGED_CODE();
 
@@ -238,38 +186,30 @@ ExDestroyHandleTable(IN PHANDLE_TABLE HandleTable,
                EVENT_INCREMENT,
                FALSE);
 
-  /* remove the handle table from the global handle table list */
-  ExAcquireHandleTableListLock();
-  RemoveEntryList(&HandleTable->HandleTableList);
-  ExReleaseHandleTableListLock();
-
   /* call the callback function to cleanup the objects associated with the
      handle table */
-  if(DestroyHandleCallback != NULL)
+  for(tlp = HandleTable->Table, lasttlp = HandleTable->Table + N_TOPLEVEL_POINTERS;
+      tlp != lasttlp;
+      tlp++)
   {
-    for(tlp = HandleTable->Table, lasttlp = HandleTable->Table + N_TOPLEVEL_POINTERS;
-        tlp != lasttlp;
-        tlp++)
+    if((*tlp) != NULL)
     {
-      if((*tlp) != NULL)
+      for(mlp = *tlp, lastmlp = (*tlp) + N_MIDDLELEVEL_POINTERS;
+          mlp != lastmlp;
+          mlp++)
       {
-        for(mlp = *tlp, lastmlp = (*tlp) + N_MIDDLELEVEL_POINTERS;
-            mlp != lastmlp;
-            mlp++)
+        if((*mlp) != NULL)
         {
-          if((*mlp) != NULL)
-          {
-            PHANDLE_TABLE_ENTRY curee, laste;
+          PHANDLE_TABLE_ENTRY curee, laste;
 
-            for(curee = *mlp, laste = *mlp + N_SUBHANDLE_ENTRIES;
-                curee != laste;
-                curee++)
+          for(curee = *mlp, laste = *mlp + N_SUBHANDLE_ENTRIES;
+              curee != laste;
+              curee++)
+          {
+            if(curee->u1.Object != NULL && SweepHandleCallback != NULL)
             {
-              if(curee->u1.Object != NULL && ExLockHandleTableEntryNoDestructionCheck(HandleTable, curee))
-              {
-                DestroyHandleCallback(HandleTable, curee->u1.Object, curee->u2.GrantedAccess, Context);
-                ExUnlockHandleTableEntry(HandleTable, curee);
-              }
+              curee->u1.ObAttributes |= EX_HANDLE_ENTRY_LOCKED;
+              SweepHandleCallback(HandleTable, curee->u1.Object, curee->u2.GrantedAccess, Context);
             }
           }
         }
@@ -277,6 +217,34 @@ ExDestroyHandleTable(IN PHANDLE_TABLE HandleTable,
     }
   }
 
+  ExReleaseHandleTableLock(HandleTable);
+
+  KeLeaveCriticalRegion();
+}
+
+VOID
+ExDestroyHandleTable(IN PHANDLE_TABLE HandleTable)
+{
+  PHANDLE_TABLE_ENTRY **tlp, **lasttlp, *mlp, *lastmlp;
+  PEPROCESS QuotaProcess;
+
+  PAGED_CODE();
+
+  ASSERT(HandleTable);
+  ASSERT(HandleTable->Flags & EX_HANDLE_TABLE_CLOSING);
+
+  KeEnterCriticalRegion();
+
+  /* at this point the table should not be queried or altered anymore,
+     no locks should be necessary */
+
+  ASSERT(HandleTable->Flags & EX_HANDLE_TABLE_CLOSING);
+
+  /* remove the handle table from the global handle table list */
+  ExAcquireHandleTableListLock();
+  RemoveEntryList(&HandleTable->HandleTableList);
+  ExReleaseHandleTableListLock();
+
   QuotaProcess = HandleTable->QuotaProcess;
 
   /* free the tables */
@@ -310,8 +278,6 @@ ExDestroyHandleTable(IN PHANDLE_TABLE HandleTable,
     }
   }
 
-  ExReleaseHandleTableLock(HandleTable);
-
   KeLeaveCriticalRegion();
 
   /* free the handle table */
@@ -408,9 +374,7 @@ freehandletable:
 
           ExReleaseHandleTableLock(SourceHandleTable);
 
-          ExDestroyHandleTable(HandleTable,
-                               NULL,
-                               NULL);
+          ExDestroyHandleTable(HandleTable);
           /* allocate an empty handle table */
           return ExCreateHandleTable(QuotaProcess);
         }
index bd9fb1b..0e38d13 100644 (file)
@@ -91,7 +91,7 @@ ExpInitializeProfileImplementation(VOID);
                                    EX_HANDLE_ENTRY_INHERITABLE |               \
                                    EX_HANDLE_ENTRY_AUDITONCLOSE)
 
-typedef VOID (STDCALL PEX_DESTROY_HANDLE_CALLBACK)(
+typedef VOID (STDCALL PEX_SWEEP_HANDLE_CALLBACK)(
     PHANDLE_TABLE HandleTable, 
     PVOID Object, 
     ULONG GrantedAccess, 
@@ -118,8 +118,13 @@ ExCreateHandleTable(IN PEPROCESS QuotaProcess  OPTIONAL);
 
 VOID
 ExDestroyHandleTable(
+    IN PHANDLE_TABLE HandleTable
+);
+
+VOID
+ExSweepHandleTable(
     IN PHANDLE_TABLE HandleTable,
-    IN PEX_DESTROY_HANDLE_CALLBACK DestroyHandleCallback  OPTIONAL,
+    IN PEX_SWEEP_HANDLE_CALLBACK SweepHandleCallback  OPTIONAL,
     IN PVOID Context  OPTIONAL
 );
 
index 6176766..153ff10 100644 (file)
@@ -504,10 +504,10 @@ NtDuplicateObject (IN     HANDLE          SourceProcessHandle,
 }
 
 static VOID STDCALL
-DeleteHandleCallback(PHANDLE_TABLE HandleTable,
-                     PVOID Object,
-                     ULONG GrantedAccess,
-                     PVOID Context)
+SweepHandleCallback(PHANDLE_TABLE HandleTable,
+                    PVOID Object,
+                    ULONG GrantedAccess,
+                    PVOID Context)
 {
   POBJECT_HEADER ObjectHeader;
   PVOID ObjectBody;
@@ -580,9 +580,12 @@ ObKillProcess(PEPROCESS Process)
 {
    PAGED_CODE();
 
-   ExDestroyHandleTable(Process->ObjectTable,
-                        DeleteHandleCallback,
-                        Process);
+   /* FIXME - Temporary hack: sweep and destroy here, needs to be fixed!!! */
+   ExSweepHandleTable(Process->ObjectTable,
+                      SweepHandleCallback,
+                      Process);
+   ExDestroyHandleTable(Process->ObjectTable);
+   Process->ObjectTable = NULL;
 }
 
 
index 34ad4a1..d966de6 100644 (file)
@@ -225,23 +225,15 @@ RtlpCreateAtomHandleTable(PRTL_ATOM_TABLE AtomTable)
    return (AtomTable->ExHandleTable != NULL);
 }
 
-static VOID STDCALL
-AtomDeleteHandleCallback(PHANDLE_TABLE HandleTable,
-                         PVOID Object,
-                         ULONG GrantedAccess,
-                         PVOID Context)
-{
-   return;
-}
-
 VOID
 RtlpDestroyAtomHandleTable(PRTL_ATOM_TABLE AtomTable)
 {
    if (AtomTable->ExHandleTable)
    {
-      ExDestroyHandleTable(AtomTable->ExHandleTable,
-                           AtomDeleteHandleCallback,
-                           AtomTable);
+      ExSweepHandleTable(AtomTable->ExHandleTable,
+                         NULL,
+                         NULL);
+      ExDestroyHandleTable(AtomTable->ExHandleTable);
       AtomTable->ExHandleTable = NULL;
    }
 }