ACPI_STATUS AcpiOsAcquireMutex( ACPI_MUTEX Handle, UINT16 Timeout) { if (!Handle) { DPRINT1("Bad parameter\n"); return AE_BAD_PARAMETER; } /* Check what the caller wants us to do */ if (Timeout == ACPI_DO_NOT_WAIT) { /* Try to acquire without waiting */ if (!ExTryToAcquireFastMutex((PFAST_MUTEX)Handle)) return AE_TIME; } else { /* Block until we get it */ ExAcquireFastMutex((PFAST_MUTEX)Handle); } return AE_OK; }
VOID Secondary_TryCloseFilExts( PSECONDARY Secondary ) { PLIST_ENTRY listEntry; Secondary_Reference( Secondary ); if (ExTryToAcquireFastMutex(&Secondary->RecoveryCcbQMutex) == FALSE) { Secondary_Dereference(Secondary); return; } if (BooleanFlagOn(Secondary->Flags, SECONDARY_FLAG_RECONNECTING)) { ExReleaseFastMutex(&Secondary->RecoveryCcbQMutex); Secondary_Dereference(Secondary); return; } listEntry = Secondary->RecoveryCcbQueue.Flink; while (listEntry != &Secondary->RecoveryCcbQueue) { PCCB ccb; PFCB fcb; PSECTION_OBJECT_POINTERS section; BOOLEAN dataSectionExists; BOOLEAN imageSectionExists; IRP_CONTEXT IrpContext; ccb = CONTAINING_RECORD( listEntry, CCB, ListEntry ); listEntry = listEntry->Flink; if (ccb->Fcb == NULL) { ASSERT(NDFAT_BUG); continue; } if (NodeType(ccb->Fcb) != FAT_NTC_FCB) continue; fcb = ccb->Fcb; if (fcb->UncleanCount != 0 || fcb->NonCachedUncleanCount != 0) { DebugTrace2( 0, Dbg, ("Secondary_TryCloseFilExts: fcb->FullFileName = %wZ\n", &ccb->Fcb->FullFileName) ); break; } DebugTrace2( 0, Dbg, ("Secondary_TryCloseFilExts: fcb->FullFileName = %wZ\n", &ccb->Fcb->FullFileName) ); RtlZeroMemory( &IrpContext, sizeof(IRP_CONTEXT) ); SetFlag( IrpContext.Flags, IRP_CONTEXT_FLAG_WAIT ); section = &fcb->NonPaged->SectionObjectPointers; if (section == NULL) break; dataSectionExists = (BOOLEAN)(section->DataSectionObject != NULL); imageSectionExists = (BOOLEAN)(section->ImageSectionObject != NULL); if (imageSectionExists) { (VOID)MmFlushImageSection( section, MmFlushForWrite ); } if (dataSectionExists) { CcPurgeCacheSection( section, NULL, 0, FALSE ); } } ExReleaseFastMutex( &Secondary->RecoveryCcbQMutex ); Secondary_Dereference( Secondary ); return; }
VOID ReadonlyTryCloseCcb ( IN PREADONLY Readonly ) { PLIST_ENTRY listEntry; Readonly_Reference( Readonly ); if (ExTryToAcquireFastMutex(&Readonly->CcbQMutex) == FALSE) { Readonly_Dereference( Readonly ); return; } listEntry = Readonly->CcbQueue.Flink; while (listEntry != &Readonly->CcbQueue) { PNDAS_CCB ccb = NULL; PNDAS_FCB fcb; PSECTION_OBJECT_POINTERS section; BOOLEAN dataSectionExists; BOOLEAN imageSectionExists; ccb = CONTAINING_RECORD( listEntry, NDAS_CCB, ListEntry ); listEntry = listEntry->Flink; if (ccb->TypeOfOpen != UserFileOpen) break; fcb = ccb->Fcb; if (fcb == NULL) { ASSERT( LFS_BUG ); break; } SPY_LOG_PRINT( LFS_DEBUG_READONLY_TRACE, ("ReadonlyTryCloseCcb: fcb->FullFileName = %wZ\n", &fcb->FullFileName) ); if (fcb->UncleanCount != 0) { SPY_LOG_PRINT( LFS_DEBUG_SECONDARY_TRACE, ("ReadonlyTryCloseCcb: fcb->FullFileName = %wZ\n", &fcb->FullFileName) ); break; } if (fcb->Header.PagingIoResource != NULL) { ASSERT( LFS_REQUIRED ); break; } section = &fcb->NonPaged->SectionObjectPointers; if (section == NULL) break; //CcFlushCache(section, NULL, 0, &ioStatusBlock); dataSectionExists = (BOOLEAN)(section->DataSectionObject != NULL); imageSectionExists = (BOOLEAN)(section->ImageSectionObject != NULL); if (imageSectionExists) { (VOID)MmFlushImageSection( section, MmFlushForWrite ); } if (dataSectionExists) { CcPurgeCacheSection( section, NULL, 0, FALSE ); } } ExReleaseFastMutex( &Readonly->CcbQMutex ); Readonly_Dereference( Readonly ); return; }
static VOID TestFastMutex( PFAST_MUTEX Mutex, KIRQL OriginalIrql) { PKTHREAD Thread = KeGetCurrentThread(); ok_irql(OriginalIrql); /* acquire/release normally */ ExAcquireFastMutex(Mutex); CheckMutex(Mutex, 0L, Thread, 0LU, OriginalIrql, APC_LEVEL); ok_bool_false(ExTryToAcquireFastMutex(Mutex), "ExTryToAcquireFastMutex returned"); CheckMutex(Mutex, 0L, Thread, 0LU, OriginalIrql, APC_LEVEL); ExReleaseFastMutex(Mutex); CheckMutex(Mutex, 1L, NULL, 0LU, OriginalIrql, OriginalIrql); #ifdef _M_IX86 /* ntoskrnl's fastcall version */ ExiAcquireFastMutex(Mutex); CheckMutex(Mutex, 0L, Thread, 0LU, OriginalIrql, APC_LEVEL); ok_bool_false(ExiTryToAcquireFastMutex(Mutex), "ExiTryToAcquireFastMutex returned"); CheckMutex(Mutex, 0L, Thread, 0LU, OriginalIrql, APC_LEVEL); ExiReleaseFastMutex(Mutex); CheckMutex(Mutex, 1L, NULL, 0LU, OriginalIrql, OriginalIrql); #endif /* try to acquire */ ok_bool_true(ExTryToAcquireFastMutex(Mutex), "ExTryToAcquireFastMutex returned"); CheckMutex(Mutex, 0L, Thread, 0LU, OriginalIrql, APC_LEVEL); ExReleaseFastMutex(Mutex); CheckMutex(Mutex, 1L, NULL, 0LU, OriginalIrql, OriginalIrql); /* shortcut functions with critical region */ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(Mutex); ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned"); ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(Mutex); /* acquire/release unsafe */ if (!KmtIsCheckedBuild || OriginalIrql == APC_LEVEL) { ExAcquireFastMutexUnsafe(Mutex); CheckMutex(Mutex, 0L, Thread, 0LU, OriginalIrql, OriginalIrql); ExReleaseFastMutexUnsafe(Mutex); CheckMutex(Mutex, 1L, NULL, 0LU, OriginalIrql, OriginalIrql); /* mismatched acquire/release */ ExAcquireFastMutex(Mutex); CheckMutex(Mutex, 0L, Thread, 0LU, OriginalIrql, APC_LEVEL); ExReleaseFastMutexUnsafe(Mutex); CheckMutex(Mutex, 1L, NULL, 0LU, OriginalIrql, APC_LEVEL); KmtSetIrql(OriginalIrql); CheckMutex(Mutex, 1L, NULL, 0LU, OriginalIrql, OriginalIrql); Mutex->OldIrql = 0x55555555LU; ExAcquireFastMutexUnsafe(Mutex); CheckMutex(Mutex, 0L, Thread, 0LU, 0x55555555LU, OriginalIrql); Mutex->OldIrql = PASSIVE_LEVEL; ExReleaseFastMutex(Mutex); CheckMutex(Mutex, 1L, NULL, 0LU, PASSIVE_LEVEL, PASSIVE_LEVEL); KmtSetIrql(OriginalIrql); CheckMutex(Mutex, 1L, NULL, 0LU, PASSIVE_LEVEL, OriginalIrql); } if (!KmtIsCheckedBuild) { /* release without acquire */ ExReleaseFastMutexUnsafe(Mutex); CheckMutex(Mutex, 2L, NULL, 0LU, PASSIVE_LEVEL, OriginalIrql); --Mutex->Count; Mutex->OldIrql = OriginalIrql; ExReleaseFastMutex(Mutex); CheckMutex(Mutex, 2L, NULL, 0LU, OriginalIrql, OriginalIrql); ExReleaseFastMutex(Mutex); CheckMutex(Mutex, 3L, NULL, 0LU, OriginalIrql, OriginalIrql); Mutex->Count -= 2; } /* make sure we survive this in case of error */ ok_eq_long(Mutex->Count, 1L); Mutex->Count = 1; ok_irql(OriginalIrql); KmtSetIrql(OriginalIrql); }