Author: fireball Date: Mon Sep 8 07:41:30 2008 New Revision: 36051
URL: http://svn.reactos.org/svn/reactos?rev=36051&view=rev Log: - Implement delay-close worker function. See issue #3418 for more details.
Modified: trunk/reactos/ntoskrnl/config/cmdelay.c
Modified: trunk/reactos/ntoskrnl/config/cmdelay.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmdelay.c?r... ============================================================================== --- trunk/reactos/ntoskrnl/config/cmdelay.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/config/cmdelay.c [iso-8859-1] Mon Sep 8 07:41:30 2008 @@ -54,13 +54,134 @@ NTAPI CmpDelayCloseWorker(IN PVOID Context) { + PCM_DELAYED_CLOSE_ENTRY ListEntry; + ULONG i, ConvKey; PAGED_CODE();
/* Sanity check */ ASSERT(CmpDelayCloseWorkItemActive);
- /* FIXME: TODO */ - ASSERT(FALSE); + /* Lock the registry */ + CmpLockRegistry(); + + /* Acquire the delayed close table lock */ + KeAcquireGuardedMutex(&CmpDelayedCloseTableLock); + + /* Iterate */ + for (i = 0; i < (CmpDelayedCloseSize >> 2); i++) + { + /* Break out of the loop if there is nothing to process */ + if (CmpDelayedCloseElements <= CmpDelayedCloseSize) break; + + /* Sanity check */ + ASSERT(!IsListEmpty(&CmpDelayedLRUListHead)); + + /* Get the entry */ + ListEntry = CONTAINING_RECORD(CmpDelayedLRUListHead.Blink, + CM_DELAYED_CLOSE_ENTRY, + DelayedLRUList); + + /* Save the ConvKey value of the KCB */ + ConvKey = ListEntry->KeyControlBlock->ConvKey; + + /* Release the delayed close table lock */ + KeReleaseGuardedMutex(&CmpDelayedCloseTableLock); + + /* Acquire the KCB lock */ + CmpAcquireKcbLockExclusiveByKey(ConvKey); + + /* Reacquire the delayed close table lock */ + KeAcquireGuardedMutex(&CmpDelayedCloseTableLock); + + /* Get the entry */ + ListEntry = CONTAINING_RECORD(CmpDelayedLRUListHead.Blink, + CM_DELAYED_CLOSE_ENTRY, + DelayedLRUList); + + /* Is the entry we have still the first one? */ + if (CmpDelayedCloseElements <= CmpDelayedCloseSize) + { + /* No, someone already inserted an entry there */ + CmpReleaseKcbLockByKey(ConvKey); + break; + } + + /* Is it a different entry? */ + if (ConvKey != ListEntry->KeyControlBlock->ConvKey) + { + /* Release the delayed close table lock */ + KeReleaseGuardedMutex(&CmpDelayedCloseTableLock); + + /* Release the KCB lock */ + CmpReleaseKcbLockByKey(ConvKey); + + /* Reacquire the delayed close table lock */ + KeAcquireGuardedMutex(&CmpDelayedCloseTableLock); + + /* Iterate again */ + continue; + } + + /* Remove it from the end of the list */ + ListEntry = + (PCM_DELAYED_CLOSE_ENTRY)RemoveTailList(&CmpDelayedLRUListHead); + + /* Get the containing entry */ + ListEntry = CONTAINING_RECORD(ListEntry, + CM_DELAYED_CLOSE_ENTRY, + DelayedLRUList); + + /* Process the entry */ + if ((ListEntry->KeyControlBlock->RefCount) || + (ListEntry->KeyControlBlock->DelayedCloseIndex)) + { + /* Add it to the beginning of the list */ + InsertHeadList(&CmpDelayedLRUListHead, &ListEntry->DelayedLRUList); + + /* Release the delayed close table lock */ + KeReleaseGuardedMutex(&CmpDelayedCloseTableLock); + } + else + { + /* Release the delayed close table lock */ + KeReleaseGuardedMutex(&CmpDelayedCloseTableLock); + + /* Zero out the DelayCloseEntry pointer */ + ListEntry->KeyControlBlock->DelayCloseEntry = NULL; + + /* Cleanup the KCB cache */ + CmpCleanUpKcbCacheWithLock(ListEntry->KeyControlBlock, FALSE); + + /* Free the delay item */ + CmpFreeDelayItem(ListEntry); + + /* Decrement delayed close elements count */ + InterlockedDecrement((PLONG)&CmpDelayedCloseElements); + } + + /* Release the KCB lock */ + CmpReleaseKcbLockByKey(ConvKey); + + /* Reacquire the delayed close table lock */ + KeAcquireGuardedMutex(&CmpDelayedCloseTableLock); + } + + if (CmpDelayedCloseElements <= CmpDelayedCloseSize) + { + /* We're not active anymore */ + CmpDelayCloseWorkItemActive = FALSE; + } + else + { + /* We didn't process all things, so reschedule for the next time */ + CmpArmDelayedCloseTimer(); + } + + /* Release the delayed close table lock */ + KeReleaseGuardedMutex(&CmpDelayedCloseTableLock); + + /* Unlock the registry */ + CmpUnlockRegistry(); }
VOID