[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