⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 recmutex.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
字号:
#include <ntddk.h>
#include "recmutex.h"

VOID RecursiveMutexInit( PRECURSIVE_MUTEX RecMutex ) {
    RtlZeroMemory( RecMutex, sizeof(*RecMutex) );
    KeInitializeSpinLock( &RecMutex->SpinLock );
    ExInitializeFastMutex( &RecMutex->Mutex );
    KeInitializeEvent( &RecMutex->StateLockedEvent, 
		       NotificationEvent, FALSE );    
}

/* NOTE: When we leave, the FAST_MUTEX must have been released.  The result
 * is that we always exit in the same irql as entering */
SIZE_T RecursiveMutexEnter( PRECURSIVE_MUTEX RecMutex, BOOLEAN ToWrite ) {
    NTSTATUS Status = STATUS_SUCCESS;
    PVOID CurrentThread = KeGetCurrentThread();

    /* Wait for the previous user to unlock the RecMutex state.  There might be
     * multiple waiters waiting to change the state.  We need to check each
     * time we get the event whether somebody still has the state locked */

    if( !RecMutex ) return FALSE;

    if( CurrentThread == RecMutex->CurrentThread || 
	(!ToWrite && !RecMutex->Writer) ) {
	RecMutex->LockCount++;
	return TRUE;
    }

    if( KeGetCurrentIrql() == PASSIVE_LEVEL ) {
	ExAcquireFastMutex( &RecMutex->Mutex );
	RecMutex->OldIrql = PASSIVE_LEVEL;
	while( RecMutex->Locked ) {
	    ExReleaseFastMutex( &RecMutex->Mutex );
	    Status = KeWaitForSingleObject( &RecMutex->StateLockedEvent,
					    UserRequest,
					    KernelMode,
					    FALSE,
					    NULL );
	    ExAcquireFastMutex( &RecMutex->Mutex );
	}
	RecMutex->Locked = TRUE;
	RecMutex->Writer = ToWrite;
	RecMutex->CurrentThread = CurrentThread;
	RecMutex->LockCount++;
	ExReleaseFastMutex( &RecMutex->Mutex );
    } else {
	KeAcquireSpinLock( &RecMutex->SpinLock, &RecMutex->OldIrql );
	RecMutex->Locked = TRUE;
	RecMutex->Writer = ToWrite;
	RecMutex->CurrentThread = CurrentThread;
	RecMutex->LockCount++;
    }

    return TRUE;
}

VOID RecursiveMutexLeave( PRECURSIVE_MUTEX RecMutex ) {
    if( RecMutex->LockCount == 0 ) {
	return;
    } else
	RecMutex->LockCount--;

    if( !RecMutex->LockCount ) {
	RecMutex->CurrentThread = NULL;
	if( RecMutex->OldIrql == PASSIVE_LEVEL ) {
	    ExAcquireFastMutex( &RecMutex->Mutex );
	    RecMutex->Locked = FALSE;
	    RecMutex->Writer = FALSE;
	    ExReleaseFastMutex( &RecMutex->Mutex );
	} else {
	    RecMutex->Locked = FALSE;
	    RecMutex->Writer = FALSE;
	    KeReleaseSpinLock( &RecMutex->SpinLock, RecMutex->OldIrql );
	}

	RecMutex->OldIrql = PASSIVE_LEVEL;
	KePulseEvent( &RecMutex->StateLockedEvent, IO_NETWORK_INCREMENT, 
		      FALSE );
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -