Module: wine Branch: master Commit: 02ee5bb52da578a7ef71be104666983442e23512 URL: http://source.winehq.org/git/wine.git/?a=commit;h=02ee5bb52da578a7ef71be1046...
Author: Sebastian Lackner sebastian@fds-team.de Date: Wed Jul 1 22:56:14 2015 +0200
ntdll: Implement TpCallbackReleaseMutexOnCompletion.
Various internal details about the order and error handling of completion actions are documented in "Concurrent Programming on Windows" by Joe Duffy.
---
dlls/ntdll/ntdll.spec | 1 + dlls/ntdll/threadpool.c | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+)
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 5cfcfd7..4ccb3e7 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -975,6 +975,7 @@ @ stdcall TpAllocWork(ptr ptr ptr ptr) @ stdcall TpCallbackLeaveCriticalSectionOnCompletion(ptr ptr) @ stdcall TpCallbackMayRunLong(ptr) +@ stdcall TpCallbackReleaseMutexOnCompletion(ptr long) @ stdcall TpPostWork(ptr) @ stdcall TpReleaseCleanupGroup(ptr) @ stdcall TpReleaseCleanupGroupMembers(ptr long ptr) diff --git a/dlls/ntdll/threadpool.c b/dlls/ntdll/threadpool.c index 21e5b7d..28dd88b 100644 --- a/dlls/ntdll/threadpool.c +++ b/dlls/ntdll/threadpool.c @@ -206,6 +206,7 @@ struct threadpool_instance struct { CRITICAL_SECTION *critical_section; + HANDLE mutex; } cleanup; };
@@ -1635,6 +1636,7 @@ static void CALLBACK threadpool_worker_proc( void *param ) instance.threadid = GetCurrentThreadId(); instance.may_run_long = object->may_run_long; instance.cleanup.critical_section = NULL; + instance.cleanup.mutex = NULL;
switch (object->type) { @@ -1675,6 +1677,10 @@ static void CALLBACK threadpool_worker_proc( void *param ) { RtlLeaveCriticalSection( instance.cleanup.critical_section ); } + if (instance.cleanup.mutex) + { + NtReleaseMutant( instance.cleanup.mutex, NULL ); + }
RtlEnterCriticalSection( &pool->cs ); pool->num_busy_workers--; @@ -1827,6 +1833,19 @@ NTSTATUS WINAPI TpCallbackMayRunLong( TP_CALLBACK_INSTANCE *instance ) }
/*********************************************************************** + * TpCallbackReleaseMutexOnCompletion (NTDLL.@) + */ +VOID WINAPI TpCallbackReleaseMutexOnCompletion( TP_CALLBACK_INSTANCE *instance, HANDLE mutex ) +{ + struct threadpool_instance *this = impl_from_TP_CALLBACK_INSTANCE( instance ); + + TRACE( "%p %p\n", instance, mutex ); + + if (!this->cleanup.mutex) + this->cleanup.mutex = mutex; +} + +/*********************************************************************** * TpPostWork (NTDLL.@) */ VOID WINAPI TpPostWork( TP_WORK *work )