[6/11] ntdll: Implement TpCallbackLeaveCriticalSectionOnCompletion.
Sebastian Lackner
sebastian at fds-team.de
Wed Jul 1 15:55:52 CDT 2015
An instance can only have one completion of each type, trying to add a
second one leads to an exception on Windows.
---
dlls/ntdll/ntdll.spec | 1 +
dlls/ntdll/threadpool.c | 24 ++++++++++++++++++++++++
2 files changed, 25 insertions(+)
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index 5a698c4..5cfcfd7 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -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)
diff --git a/dlls/ntdll/threadpool.c b/dlls/ntdll/threadpool.c
index a0090c0..21e5b7d 100644
--- a/dlls/ntdll/threadpool.c
+++ b/dlls/ntdll/threadpool.c
@@ -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--;
@@ -1753,6 +1764,19 @@ NTSTATUS WINAPI TpAllocWork( TP_WORK **out, PTP_WORK_CALLBACK callback, PVOID us
}
/***********************************************************************
+ * 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.@)
*/
NTSTATUS WINAPI TpCallbackMayRunLong( TP_CALLBACK_INSTANCE *instance )
--
2.4.4
More information about the wine-patches
mailing list