mirror of
https://github.com/reactos/reactos.git
synced 2024-10-02 07:26:47 +00:00
implemented sweeping of handle tables
svn path=/trunk/; revision=19951
This commit is contained in:
parent
e6894eb9f9
commit
db41ecbbff
|
@ -11,7 +11,6 @@
|
||||||
*
|
*
|
||||||
* - the last entry of a subhandle list should be reserved for auditing
|
* - the last entry of a subhandle list should be reserved for auditing
|
||||||
*
|
*
|
||||||
* ExSweepHandleTable (???)
|
|
||||||
* ExReferenceHandleDebugInfo
|
* ExReferenceHandleDebugInfo
|
||||||
* ExSnapShotHandleTables
|
* ExSnapShotHandleTables
|
||||||
* ExpMoveFreeHandles (???)
|
* ExpMoveFreeHandles (???)
|
||||||
|
@ -163,63 +162,12 @@ ExCreateHandleTable(IN PEPROCESS QuotaProcess OPTIONAL)
|
||||||
return HandleTable;
|
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
|
VOID
|
||||||
ExDestroyHandleTable(IN PHANDLE_TABLE HandleTable,
|
ExSweepHandleTable(IN PHANDLE_TABLE HandleTable,
|
||||||
IN PEX_DESTROY_HANDLE_CALLBACK DestroyHandleCallback OPTIONAL,
|
IN PEX_SWEEP_HANDLE_CALLBACK SweepHandleCallback OPTIONAL,
|
||||||
IN PVOID Context OPTIONAL)
|
IN PVOID Context OPTIONAL)
|
||||||
{
|
{
|
||||||
PHANDLE_TABLE_ENTRY **tlp, **lasttlp, *mlp, *lastmlp;
|
PHANDLE_TABLE_ENTRY **tlp, **lasttlp, *mlp, *lastmlp;
|
||||||
PEPROCESS QuotaProcess;
|
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
|
@ -238,15 +186,8 @@ ExDestroyHandleTable(IN PHANDLE_TABLE HandleTable,
|
||||||
EVENT_INCREMENT,
|
EVENT_INCREMENT,
|
||||||
FALSE);
|
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
|
/* call the callback function to cleanup the objects associated with the
|
||||||
handle table */
|
handle table */
|
||||||
if(DestroyHandleCallback != NULL)
|
|
||||||
{
|
|
||||||
for(tlp = HandleTable->Table, lasttlp = HandleTable->Table + N_TOPLEVEL_POINTERS;
|
for(tlp = HandleTable->Table, lasttlp = HandleTable->Table + N_TOPLEVEL_POINTERS;
|
||||||
tlp != lasttlp;
|
tlp != lasttlp;
|
||||||
tlp++)
|
tlp++)
|
||||||
|
@ -265,11 +206,10 @@ ExDestroyHandleTable(IN PHANDLE_TABLE HandleTable,
|
||||||
curee != laste;
|
curee != laste;
|
||||||
curee++)
|
curee++)
|
||||||
{
|
{
|
||||||
if(curee->u1.Object != NULL && ExLockHandleTableEntryNoDestructionCheck(HandleTable, curee))
|
if(curee->u1.Object != NULL && SweepHandleCallback != NULL)
|
||||||
{
|
{
|
||||||
DestroyHandleCallback(HandleTable, curee->u1.Object, curee->u2.GrantedAccess, Context);
|
curee->u1.ObAttributes |= EX_HANDLE_ENTRY_LOCKED;
|
||||||
ExUnlockHandleTableEntry(HandleTable, curee);
|
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;
|
QuotaProcess = HandleTable->QuotaProcess;
|
||||||
|
|
||||||
/* free the tables */
|
/* free the tables */
|
||||||
|
@ -310,8 +278,6 @@ ExDestroyHandleTable(IN PHANDLE_TABLE HandleTable,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ExReleaseHandleTableLock(HandleTable);
|
|
||||||
|
|
||||||
KeLeaveCriticalRegion();
|
KeLeaveCriticalRegion();
|
||||||
|
|
||||||
/* free the handle table */
|
/* free the handle table */
|
||||||
|
@ -408,9 +374,7 @@ freehandletable:
|
||||||
|
|
||||||
ExReleaseHandleTableLock(SourceHandleTable);
|
ExReleaseHandleTableLock(SourceHandleTable);
|
||||||
|
|
||||||
ExDestroyHandleTable(HandleTable,
|
ExDestroyHandleTable(HandleTable);
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
/* allocate an empty handle table */
|
/* allocate an empty handle table */
|
||||||
return ExCreateHandleTable(QuotaProcess);
|
return ExCreateHandleTable(QuotaProcess);
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,7 +91,7 @@ ExpInitializeProfileImplementation(VOID);
|
||||||
EX_HANDLE_ENTRY_INHERITABLE | \
|
EX_HANDLE_ENTRY_INHERITABLE | \
|
||||||
EX_HANDLE_ENTRY_AUDITONCLOSE)
|
EX_HANDLE_ENTRY_AUDITONCLOSE)
|
||||||
|
|
||||||
typedef VOID (STDCALL PEX_DESTROY_HANDLE_CALLBACK)(
|
typedef VOID (STDCALL PEX_SWEEP_HANDLE_CALLBACK)(
|
||||||
PHANDLE_TABLE HandleTable,
|
PHANDLE_TABLE HandleTable,
|
||||||
PVOID Object,
|
PVOID Object,
|
||||||
ULONG GrantedAccess,
|
ULONG GrantedAccess,
|
||||||
|
@ -118,8 +118,13 @@ ExCreateHandleTable(IN PEPROCESS QuotaProcess OPTIONAL);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
ExDestroyHandleTable(
|
ExDestroyHandleTable(
|
||||||
|
IN PHANDLE_TABLE HandleTable
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
ExSweepHandleTable(
|
||||||
IN PHANDLE_TABLE HandleTable,
|
IN PHANDLE_TABLE HandleTable,
|
||||||
IN PEX_DESTROY_HANDLE_CALLBACK DestroyHandleCallback OPTIONAL,
|
IN PEX_SWEEP_HANDLE_CALLBACK SweepHandleCallback OPTIONAL,
|
||||||
IN PVOID Context OPTIONAL
|
IN PVOID Context OPTIONAL
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -504,7 +504,7 @@ NtDuplicateObject (IN HANDLE SourceProcessHandle,
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID STDCALL
|
static VOID STDCALL
|
||||||
DeleteHandleCallback(PHANDLE_TABLE HandleTable,
|
SweepHandleCallback(PHANDLE_TABLE HandleTable,
|
||||||
PVOID Object,
|
PVOID Object,
|
||||||
ULONG GrantedAccess,
|
ULONG GrantedAccess,
|
||||||
PVOID Context)
|
PVOID Context)
|
||||||
|
@ -580,9 +580,12 @@ ObKillProcess(PEPROCESS Process)
|
||||||
{
|
{
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
ExDestroyHandleTable(Process->ObjectTable,
|
/* FIXME - Temporary hack: sweep and destroy here, needs to be fixed!!! */
|
||||||
DeleteHandleCallback,
|
ExSweepHandleTable(Process->ObjectTable,
|
||||||
|
SweepHandleCallback,
|
||||||
Process);
|
Process);
|
||||||
|
ExDestroyHandleTable(Process->ObjectTable);
|
||||||
|
Process->ObjectTable = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -225,23 +225,15 @@ RtlpCreateAtomHandleTable(PRTL_ATOM_TABLE AtomTable)
|
||||||
return (AtomTable->ExHandleTable != NULL);
|
return (AtomTable->ExHandleTable != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID STDCALL
|
|
||||||
AtomDeleteHandleCallback(PHANDLE_TABLE HandleTable,
|
|
||||||
PVOID Object,
|
|
||||||
ULONG GrantedAccess,
|
|
||||||
PVOID Context)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
RtlpDestroyAtomHandleTable(PRTL_ATOM_TABLE AtomTable)
|
RtlpDestroyAtomHandleTable(PRTL_ATOM_TABLE AtomTable)
|
||||||
{
|
{
|
||||||
if (AtomTable->ExHandleTable)
|
if (AtomTable->ExHandleTable)
|
||||||
{
|
{
|
||||||
ExDestroyHandleTable(AtomTable->ExHandleTable,
|
ExSweepHandleTable(AtomTable->ExHandleTable,
|
||||||
AtomDeleteHandleCallback,
|
NULL,
|
||||||
AtomTable);
|
NULL);
|
||||||
|
ExDestroyHandleTable(AtomTable->ExHandleTable);
|
||||||
AtomTable->ExHandleTable = NULL;
|
AtomTable->ExHandleTable = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue