mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
144 lines
5.3 KiB
Diff
144 lines
5.3 KiB
Diff
From 0a7df47900ff847f137836341d086dc5690f97d7 Mon Sep 17 00:00:00 2001
|
|
From: Zebediah Figura <z.figura12@gmail.com>
|
|
Date: Tue, 29 Jan 2019 21:35:44 -0600
|
|
Subject: [PATCH 02/13] ntoskrnl.exe: Implement
|
|
ExAcquireResourceExclusiveLite().
|
|
|
|
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
|
|
---
|
|
dlls/ntoskrnl.exe/ntoskrnl.c | 9 -----
|
|
dlls/ntoskrnl.exe/sync.c | 73 ++++++++++++++++++++++++++++++++++++
|
|
include/ddk/wdm.h | 1 +
|
|
3 files changed, 74 insertions(+), 9 deletions(-)
|
|
|
|
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
|
|
index 93ba89be..d6c35d1c 100644
|
|
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
|
|
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
|
|
@@ -3038,15 +3038,6 @@ NTSTATUS WINAPI IoCsqInitialize(PIO_CSQ csq, PIO_CSQ_INSERT_IRP insert_irp, PIO_
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
-/***********************************************************************
|
|
- * ExAcquireResourceExclusiveLite (NTOSKRNL.EXE.@)
|
|
- */
|
|
-BOOLEAN WINAPI ExAcquireResourceExclusiveLite( PERESOURCE resource, BOOLEAN wait )
|
|
-{
|
|
- FIXME( ":%p %u stub\n", resource, wait );
|
|
- return TRUE;
|
|
-}
|
|
-
|
|
/***********************************************************************
|
|
* ExDeleteResourceLite (NTOSKRNL.EXE.@)
|
|
*/
|
|
diff --git a/dlls/ntoskrnl.exe/sync.c b/dlls/ntoskrnl.exe/sync.c
|
|
index 56d46a86..205914a7 100644
|
|
--- a/dlls/ntoskrnl.exe/sync.c
|
|
+++ b/dlls/ntoskrnl.exe/sync.c
|
|
@@ -30,6 +30,7 @@
|
|
#include "ddk/wdm.h"
|
|
|
|
#include "wine/debug.h"
|
|
+#include "wine/heap.h"
|
|
|
|
#include "ntoskrnl_private.h"
|
|
|
|
@@ -664,6 +665,18 @@ void WINAPI ExReleaseFastMutexUnsafe( FAST_MUTEX *mutex )
|
|
KeSetEvent( &mutex->Event, IO_NO_INCREMENT, FALSE );
|
|
}
|
|
|
|
+/* Use of the fields of an ERESOURCE structure seems to vary wildly between
|
|
+ * Windows versions. The below implementation uses them as follows:
|
|
+ *
|
|
+ * OwnerTable - contains a list of shared owners (TID and recursion count),
|
|
+ * including threads which do not currently own the resource
|
|
+ * (recursion count == 0)
|
|
+ * OwnerEntry.OwnerThread - the owner TID if exclusively owned
|
|
+ * OwnerEntry.TableSize - the number of entries in OwnerTable, including threads
|
|
+ * which do not currently own the resource
|
|
+ * ActiveEntries - total number of acquisitions (incl. recursive ones)
|
|
+ */
|
|
+
|
|
/***********************************************************************
|
|
* ExInitializeResourceLite (NTOSKRNL.EXE.@)
|
|
*/
|
|
@@ -673,3 +686,63 @@ NTSTATUS WINAPI ExInitializeResourceLite( ERESOURCE *resource )
|
|
memset(resource, 0, sizeof(*resource));
|
|
return STATUS_SUCCESS;
|
|
}
|
|
+
|
|
+/***********************************************************************
|
|
+ * ExAcquireResourceExclusiveLite (NTOSKRNL.EXE.@)
|
|
+ */
|
|
+BOOLEAN WINAPI ExAcquireResourceExclusiveLite( ERESOURCE *resource, BOOLEAN wait )
|
|
+{
|
|
+ KIRQL irql;
|
|
+
|
|
+ TRACE("resource %p, wait %u.\n", resource, wait);
|
|
+
|
|
+ KeAcquireSpinLock( &resource->SpinLock, &irql );
|
|
+
|
|
+ FIXME("%#lx/%d/%d/%d\n", resource->OwnerEntry.OwnerThread, resource->ActiveEntries,
|
|
+ resource->NumberOfExclusiveWaiters, resource->NumberOfSharedWaiters);
|
|
+
|
|
+ if (resource->OwnerEntry.OwnerThread == (ERESOURCE_THREAD)KeGetCurrentThread())
|
|
+ {
|
|
+ resource->ActiveEntries++;
|
|
+ KeReleaseSpinLock( &resource->SpinLock, irql );
|
|
+ return TRUE;
|
|
+ }
|
|
+ else if (!resource->ActiveEntries && !resource->NumberOfExclusiveWaiters && !resource->NumberOfSharedWaiters)
|
|
+ {
|
|
+ /* In order to avoid a race between waiting for the ExclusiveWaiters
|
|
+ * event and grabbing the lock, do not grab the resource if it is
|
|
+ * unclaimed but has waiters; instead queue ourselves. */
|
|
+ resource->Flag |= ResourceOwnedExclusive;
|
|
+ resource->OwnerEntry.OwnerThread = (ERESOURCE_THREAD)KeGetCurrentThread();
|
|
+ resource->ActiveEntries++;
|
|
+ KeReleaseSpinLock( &resource->SpinLock, irql );
|
|
+ return TRUE;
|
|
+ }
|
|
+ else if (!wait)
|
|
+ {
|
|
+ KeReleaseSpinLock( &resource->SpinLock, irql );
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ if (!resource->ExclusiveWaiters)
|
|
+ {
|
|
+ resource->ExclusiveWaiters = heap_alloc( sizeof(*resource->ExclusiveWaiters) );
|
|
+ KeInitializeEvent( resource->ExclusiveWaiters, SynchronizationEvent, FALSE );
|
|
+ }
|
|
+ resource->NumberOfExclusiveWaiters++;
|
|
+
|
|
+ KeReleaseSpinLock( &resource->SpinLock, irql );
|
|
+
|
|
+ KeWaitForSingleObject( resource->ExclusiveWaiters, Executive, KernelMode, FALSE, NULL );
|
|
+
|
|
+ KeAcquireSpinLock( &resource->SpinLock, &irql );
|
|
+
|
|
+ resource->Flag |= ResourceOwnedExclusive;
|
|
+ resource->OwnerEntry.OwnerThread = (ERESOURCE_THREAD)KeGetCurrentThread();
|
|
+ resource->ActiveEntries++;
|
|
+ resource->NumberOfExclusiveWaiters--;
|
|
+
|
|
+ KeReleaseSpinLock( &resource->SpinLock, irql );
|
|
+
|
|
+ return TRUE;
|
|
+}
|
|
diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h
|
|
index f76444f1..a8cbdc2e 100644
|
|
--- a/include/ddk/wdm.h
|
|
+++ b/include/ddk/wdm.h
|
|
@@ -1512,6 +1512,7 @@ static inline void IoSetCompletionRoutine(IRP *irp, PIO_COMPLETION_ROUTINE routi
|
|
|
|
NTSTATUS WINAPI DbgQueryDebugFilterState(ULONG, ULONG);
|
|
void WINAPI ExAcquireFastMutexUnsafe(PFAST_MUTEX);
|
|
+BOOLEAN WINAPI ExAcquireResourceExclusiveLite(ERESOURCE*,BOOLEAN);
|
|
PVOID WINAPI ExAllocatePool(POOL_TYPE,SIZE_T);
|
|
PVOID WINAPI ExAllocatePoolWithQuota(POOL_TYPE,SIZE_T);
|
|
PVOID WINAPI ExAllocatePoolWithTag(POOL_TYPE,SIZE_T,ULONG);
|
|
--
|
|
2.20.1
|
|
|