Commit 02ee5bb5 authored by Sebastian Lackner's avatar Sebastian Lackner Committed by Alexandre Julliard

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.
parent a9dd37be
...@@ -975,6 +975,7 @@ ...@@ -975,6 +975,7 @@
@ stdcall TpAllocWork(ptr ptr ptr ptr) @ stdcall TpAllocWork(ptr ptr ptr ptr)
@ stdcall TpCallbackLeaveCriticalSectionOnCompletion(ptr ptr) @ stdcall TpCallbackLeaveCriticalSectionOnCompletion(ptr ptr)
@ stdcall TpCallbackMayRunLong(ptr) @ stdcall TpCallbackMayRunLong(ptr)
@ stdcall TpCallbackReleaseMutexOnCompletion(ptr long)
@ stdcall TpPostWork(ptr) @ stdcall TpPostWork(ptr)
@ stdcall TpReleaseCleanupGroup(ptr) @ stdcall TpReleaseCleanupGroup(ptr)
@ stdcall TpReleaseCleanupGroupMembers(ptr long ptr) @ stdcall TpReleaseCleanupGroupMembers(ptr long ptr)
......
...@@ -206,6 +206,7 @@ struct threadpool_instance ...@@ -206,6 +206,7 @@ struct threadpool_instance
struct struct
{ {
CRITICAL_SECTION *critical_section; CRITICAL_SECTION *critical_section;
HANDLE mutex;
} cleanup; } cleanup;
}; };
...@@ -1635,6 +1636,7 @@ static void CALLBACK threadpool_worker_proc( void *param ) ...@@ -1635,6 +1636,7 @@ static void CALLBACK threadpool_worker_proc( void *param )
instance.threadid = GetCurrentThreadId(); instance.threadid = GetCurrentThreadId();
instance.may_run_long = object->may_run_long; instance.may_run_long = object->may_run_long;
instance.cleanup.critical_section = NULL; instance.cleanup.critical_section = NULL;
instance.cleanup.mutex = NULL;
switch (object->type) switch (object->type)
{ {
...@@ -1675,6 +1677,10 @@ static void CALLBACK threadpool_worker_proc( void *param ) ...@@ -1675,6 +1677,10 @@ static void CALLBACK threadpool_worker_proc( void *param )
{ {
RtlLeaveCriticalSection( instance.cleanup.critical_section ); RtlLeaveCriticalSection( instance.cleanup.critical_section );
} }
if (instance.cleanup.mutex)
{
NtReleaseMutant( instance.cleanup.mutex, NULL );
}
RtlEnterCriticalSection( &pool->cs ); RtlEnterCriticalSection( &pool->cs );
pool->num_busy_workers--; pool->num_busy_workers--;
...@@ -1827,6 +1833,19 @@ NTSTATUS WINAPI TpCallbackMayRunLong( TP_CALLBACK_INSTANCE *instance ) ...@@ -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.@) * TpPostWork (NTDLL.@)
*/ */
VOID WINAPI TpPostWork( TP_WORK *work ) VOID WINAPI TpPostWork( TP_WORK *work )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment