mirror of
https://github.com/reactos/reactos.git
synced 2025-04-15 01:47:30 +00:00
implemented sweeping of handle tables
svn path=/trunk/; revision=19951
This commit is contained in:
parent
e6894eb9f9
commit
db41ecbbff
4 changed files with 69 additions and 105 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue