ntdll: Implement TpCallbackLeaveCriticalSectionOnCompletion.

An instance can only have one completion of each type, trying to add a
second one leads to an exception on Windows.
This commit is contained in:
Sebastian Lackner 2015-07-01 22:55:52 +02:00 committed by Alexandre Julliard
parent eb974bcd7a
commit a9dd37be68
2 changed files with 25 additions and 0 deletions

View File

@ -973,6 +973,7 @@
@ stdcall TpAllocCleanupGroup(ptr)
@ stdcall TpAllocPool(ptr ptr)
@ stdcall TpAllocWork(ptr ptr ptr ptr)
@ stdcall TpCallbackLeaveCriticalSectionOnCompletion(ptr ptr)
@ stdcall TpCallbackMayRunLong(ptr)
@ stdcall TpPostWork(ptr)
@ stdcall TpReleaseCleanupGroup(ptr)

View File

@ -203,6 +203,10 @@ struct threadpool_instance
struct threadpool_object *object;
DWORD threadid;
BOOL may_run_long;
struct
{
CRITICAL_SECTION *critical_section;
} cleanup;
};
/* internal threadpool group representation */
@ -1630,6 +1634,7 @@ static void CALLBACK threadpool_worker_proc( void *param )
instance.object = object;
instance.threadid = GetCurrentThreadId();
instance.may_run_long = object->may_run_long;
instance.cleanup.critical_section = NULL;
switch (object->type)
{
@ -1665,6 +1670,12 @@ static void CALLBACK threadpool_worker_proc( void *param )
TRACE( "callback %p returned\n", object->finalization_callback );
}
/* Execute cleanup tasks. */
if (instance.cleanup.critical_section)
{
RtlLeaveCriticalSection( instance.cleanup.critical_section );
}
RtlEnterCriticalSection( &pool->cs );
pool->num_busy_workers--;
object->num_running_callbacks--;
@ -1752,6 +1763,19 @@ NTSTATUS WINAPI TpAllocWork( TP_WORK **out, PTP_WORK_CALLBACK callback, PVOID us
return STATUS_SUCCESS;
}
/***********************************************************************
* TpCallbackLeaveCriticalSectionOnCompletion (NTDLL.@)
*/
VOID WINAPI TpCallbackLeaveCriticalSectionOnCompletion( TP_CALLBACK_INSTANCE *instance, CRITICAL_SECTION *crit )
{
struct threadpool_instance *this = impl_from_TP_CALLBACK_INSTANCE( instance );
TRACE( "%p %p\n", instance, crit );
if (!this->cleanup.critical_section)
this->cleanup.critical_section = crit;
}
/***********************************************************************
* TpCallbackMayRunLong (NTDLL.@)
*/