Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ntoskrnl.exe/ntoskrnl.c | 8 ----- dlls/ntoskrnl.exe/sync.c | 60 ++++++++++++++++++++++++++++++++++++ include/ddk/wdm.h | 1 + 3 files changed, 61 insertions(+), 8 deletions(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index 441bfc57d1..42498ad412 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -3365,14 +3365,6 @@ NTSTATUS WINAPI ExDeleteResourceLite(PERESOURCE resource) return STATUS_NOT_IMPLEMENTED; }
-/*********************************************************************** - * ExReleaseResourceForThreadLite (NTOSKRNL.EXE.@) - */ -void WINAPI ExReleaseResourceForThreadLite( PERESOURCE resource, ERESOURCE_THREAD tid ) -{ - FIXME( "stub: %p %lu\n", resource, tid ); -} - /*********************************************************************** * KeEnterCriticalRegion (NTOSKRNL.EXE.@) */ diff --git a/dlls/ntoskrnl.exe/sync.c b/dlls/ntoskrnl.exe/sync.c index e89fddcbba..88c9ea70c7 100644 --- a/dlls/ntoskrnl.exe/sync.c +++ b/dlls/ntoskrnl.exe/sync.c @@ -1006,3 +1006,63 @@ BOOLEAN WINAPI ExAcquireSharedWaitForExclusive( ERESOURCE *resource, BOOLEAN wai
return TRUE; } + +/*********************************************************************** + * ExReleaseResourceForThreadLite (NTOSKRNL.EXE.@) + */ +void WINAPI ExReleaseResourceForThreadLite( ERESOURCE *resource, ERESOURCE_THREAD thread ) +{ + OWNER_ENTRY *entry; + KIRQL irql; + + TRACE("resource %p, thread %#lx.\n", resource, thread); + + KeAcquireSpinLock( &resource->SpinLock, &irql ); + + if (resource->Flag & ResourceOwnedExclusive) + { + if (resource->OwnerEntry.OwnerThread == thread) + { + if (!--resource->ActiveEntries) + { + resource->OwnerEntry.OwnerThread = 0; + resource->Flag &= ~ResourceOwnedExclusive; + } + } + else + { + ERR("Trying to release %p for thread %#lx, but resource is exclusively owned by %#lx.\n", + resource, thread, resource->OwnerEntry.OwnerThread); + return; + } + } + else + { + entry = resource_get_shared_entry( resource, thread ); + if (entry->OwnerCount) + { + entry->OwnerCount--; + resource->ActiveEntries--; + } + else + { + ERR("Trying to release %p for thread %#lx, but resource is not owned by that thread.\n", resource, thread); + return; + } + } + + if (!resource->ActiveEntries) + { + if (resource->NumberOfExclusiveWaiters) + { + KeSetEvent( resource->ExclusiveWaiters, IO_NO_INCREMENT, FALSE ); + } + else if (resource->NumberOfSharedWaiters) + { + KeReleaseSemaphore( resource->SharedWaiters, IO_NO_INCREMENT, + resource->NumberOfSharedWaiters, FALSE ); + } + } + + KeReleaseSpinLock( &resource->SpinLock, irql ); +} diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h index 4609790a66..1a3f6bbd54 100644 --- a/include/ddk/wdm.h +++ b/include/ddk/wdm.h @@ -1529,6 +1529,7 @@ PSLIST_ENTRY WINAPI ExInterlockedPopEntrySList(PSLIST_HEADER,PKSPIN_LOCK); PSLIST_ENTRY WINAPI ExInterlockedPushEntrySList(PSLIST_HEADER,PSLIST_ENTRY,PKSPIN_LOCK); LIST_ENTRY * WINAPI ExInterlockedRemoveHeadList(LIST_ENTRY*,KSPIN_LOCK*); void WINAPI ExReleaseFastMutexUnsafe(PFAST_MUTEX); +void WINAPI ExReleaseResourceForThreadLite(ERESOURCE*,ERESOURCE_THREAD); ULONG WINAPI ExSetTimerResolution(ULONG,BOOLEAN);
void WINAPI IoAcquireCancelSpinLock(KIRQL*);