コード例 #1
0
ファイル: cmlazy.c プロジェクト: hoangduit/reactos
VOID
NTAPI
CmpLazyFlushWorker(IN PVOID Parameter)
{
    BOOLEAN ForceFlush, Result, MoreWork = FALSE;
    ULONG DirtyCount = 0;
    PAGED_CODE();

    /* Don't do anything if lazy flushing isn't enabled yet */
    if (CmpHoldLazyFlush)
    {
        DPRINT1("Lazy flush held. Bye bye.\n");
        CmpLazyFlushPending = FALSE;
        return;
    }

    /* Check if we are forcing a flush */
    ForceFlush = CmpForceForceFlush;
    if (ForceFlush)
    {
        DPRINT("Forcing flush.\n");
        /* Lock the registry exclusively */
        CmpLockRegistryExclusive();
    }
    else
    {
        DPRINT("Not forcing flush.\n");
        /* Starve writers before locking */
        InterlockedIncrement(&CmpFlushStarveWriters);
        CmpLockRegistry();
    }

    /* Flush the next hive */
    MoreWork = CmpDoFlushNextHive(ForceFlush, &Result, &DirtyCount);
    if (!MoreWork)
    {
        /* We're done */
        InterlockedIncrement((PLONG)&CmpLazyFlushCount);
    }

    /* Check if we have starved writers */
    if (!ForceFlush)
        InterlockedDecrement(&CmpFlushStarveWriters);

    /* Not pending anymore, release the registry lock */
    CmpLazyFlushPending = FALSE;
    CmpUnlockRegistry();

    DPRINT("Lazy flush done. More work to be done: %s. Entries still dirty: %u.\n",
        MoreWork ? "Yes" : "No", DirtyCount);

    if (MoreWork)
    {
        /* Relaunch the flush timer, so the remaining hives get flushed */
        CmpLazyFlush();
    }
}
コード例 #2
0
ファイル: cmlazy.c プロジェクト: HBelusca/NasuTek-Odyssey
VOID
NTAPI
CmpLazyFlushWorker(IN PVOID Parameter)
{
    BOOLEAN ForceFlush, Result, MoreWork = FALSE;
    ULONG DirtyCount = 0;
    PAGED_CODE();

    /* Don't do anything if lazy flushing isn't enabled yet */
    if (CmpHoldLazyFlush) return;
    
    /* Check if we are forcing a flush */
    ForceFlush = CmpForceForceFlush;
    if (ForceFlush)
    {
        /* Lock the registry exclusively */
        CmpLockRegistryExclusive();
    }
    else
    {
        /* Do a normal lock */
        CmpLockRegistry();
        InterlockedIncrement(&CmpFlushStarveWriters);
    }
    
    /* Flush the next hive */
    MoreWork = CmpDoFlushNextHive(ForceFlush, &Result, &DirtyCount);
    if (!MoreWork)
    {
        /* We're done */
        InterlockedIncrement((PLONG)&CmpLazyFlushCount);
    }

    /* Check if we have starved writers */
    if (!ForceFlush) InterlockedDecrement(&CmpFlushStarveWriters);

    /* Not pending anymore, release the registry lock */
    CmpLazyFlushPending = FALSE;
    CmpUnlockRegistry();
    
    /* Check if we need to flush another hive */
    if ((MoreWork) || (DirtyCount)) CmpLazyFlush();
}
コード例 #3
0
ファイル: cmdelete.c プロジェクト: BaoYu0721/WRK-1.2
VOID
CmpLateUnloadHiveWorker(
    IN PVOID Hive
    )
/*++

Routine Description:

    "Late" unloads the hive; If nothing goes badly wrong (i.e. insufficient resources),
    this function should succeed

Arguments:

    CmHive - the frozen hive to be unloaded

Return Value:

    NONE.

--*/
{
    NTSTATUS                Status;
    HCELL_INDEX             Cell;
    PCM_KEY_CONTROL_BLOCK   RootKcb;
    PCMHIVE                 CmHive;

    CM_PAGED_CODE();

    //
    // first, load the registry exclusive
    //
    CmpLockRegistryExclusive();

    //
    // hive is the parameter to this worker; make sure we free the work item
    // allocated by CmpDeleteKeyObject
    //
    CmHive = (PCMHIVE)Hive;

    ASSERT( CmHive->UnloadWorkItem != NULL );
    ExFreePool( CmHive->UnloadWorkItem );

    //
    // if this attempt doesn't succeed, mark that we can try another
    //
    CmHive->UnloadWorkItem = NULL;

    ASSERT( !(CmHive->Hive.HiveFlags & HIVE_IS_UNLOADING) );
    if( CmHive->Frozen == FALSE )  {
        //
        // another thread mounted the exact same hive in the exact same place, hence unfreezing the hive
        // we've done the cleanup part (free the workitem) nothing more to do.
        // or hive is already in process of being unloaded
        //
        ASSERT( CmHive->RootKcb == NULL );
        CmpUnlockRegistry();
        return;
    }
    //
    // this is just about the only possible way the hive can get corrupted in between
    //
    if( HvShutdownComplete == TRUE ) {
        // too late to do anything
        CmpUnlockRegistry();
        return;
    }

    //
    // hive should be frozen, otherwise we wouldn't get here
    //
    ASSERT( CmHive->Frozen == TRUE );

    RootKcb = CmHive->RootKcb;
    //
    // root kcb must be valid and has only our "artificial" refcount on it
    //
    ASSERT( RootKcb != NULL );

    if( RootKcb->RefCount > 1 ) {
        //
        // somebody else must've gotten in between dropping/reacquiring the reglock
        // and opened a handle inside this hive; bad luck, we can't unload
        //
        CmpUnlockRegistry();
        return;
    }

    ASSERT_KCB(RootKcb);

    Cell = RootKcb->KeyCell;
    Status = CmUnloadKey(RootKcb,0,CM_UNLOAD_REG_LOCKED_EX);
    ASSERT( (Status != STATUS_CANNOT_DELETE) && (Status != STATUS_INVALID_PARAMETER) );

    if(NT_SUCCESS(Status)) {
        // CmUnloadKey already released the lock
        CmpLockRegistry();
        CmpDereferenceKeyControlBlock(RootKcb);
    } 
    CmpUnlockRegistry();
}