Sebastian Lackner : ntdll: Implement threadpool work item functions.

Alexandre Julliard julliard at wine.codeweavers.com
Wed Jul 1 09:06:24 CDT 2015


Module: wine
Branch: master
Commit: e4c38f6bad3df50c71eb9b05a03d38732a854de3
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=e4c38f6bad3df50c71eb9b05a03d38732a854de3

Author: Sebastian Lackner <sebastian at fds-team.de>
Date:   Wed Jul  1 02:57:57 2015 +0200

ntdll: Implement threadpool work item functions.

---

 dlls/ntdll/ntdll.spec   |  4 +++
 dlls/ntdll/threadpool.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 96 insertions(+), 1 deletion(-)

diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index f889b04..4b5ece5 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -972,12 +972,16 @@
 @ stdcall RtlxUnicodeStringToOemSize(ptr) RtlUnicodeStringToOemSize
 @ stdcall TpAllocCleanupGroup(ptr)
 @ stdcall TpAllocPool(ptr ptr)
+@ stdcall TpAllocWork(ptr ptr ptr ptr)
+@ stdcall TpPostWork(ptr)
 @ stdcall TpReleaseCleanupGroup(ptr)
 @ stdcall TpReleaseCleanupGroupMembers(ptr long ptr)
 @ stdcall TpReleasePool(ptr)
+@ stdcall TpReleaseWork(ptr)
 @ stdcall TpSetPoolMaxThreads(ptr long)
 @ stdcall TpSetPoolMinThreads(ptr long)
 @ stdcall TpSimpleTryPost(ptr ptr ptr)
+@ stdcall TpWaitForWork(ptr long)
 @ stdcall -ret64 VerSetConditionMask(int64 long long)
 @ stdcall WinSqmIsOptedIn()
 @ stdcall ZwAcceptConnectPort(ptr long ptr long long ptr) NtAcceptConnectPort
diff --git a/dlls/ntdll/threadpool.c b/dlls/ntdll/threadpool.c
index 2e8568c..da41ba0 100644
--- a/dlls/ntdll/threadpool.c
+++ b/dlls/ntdll/threadpool.c
@@ -157,7 +157,8 @@ struct threadpool
 
 enum threadpool_objtype
 {
-    TP_OBJECT_TYPE_SIMPLE
+    TP_OBJECT_TYPE_SIMPLE,
+    TP_OBJECT_TYPE_WORK
 };
 
 /* internal threadpool object representation */
@@ -185,6 +186,10 @@ struct threadpool_object
         {
             PTP_SIMPLE_CALLBACK callback;
         } simple;
+        struct
+        {
+            PTP_WORK_CALLBACK callback;
+        } work;
     } u;
 };
 
@@ -203,6 +208,13 @@ static inline struct threadpool *impl_from_TP_POOL( TP_POOL *pool )
     return (struct threadpool *)pool;
 }
 
+static inline struct threadpool_object *impl_from_TP_WORK( TP_WORK *work )
+{
+    struct threadpool_object *object = (struct threadpool_object *)work;
+    assert( object->type == TP_OBJECT_TYPE_WORK );
+    return object;
+}
+
 static inline struct threadpool_group *impl_from_TP_CLEANUP_GROUP( TP_CLEANUP_GROUP *group )
 {
     return (struct threadpool_group *)group;
@@ -1579,6 +1591,15 @@ static void CALLBACK threadpool_worker_proc( void *param )
                     break;
                 }
 
+                case TP_OBJECT_TYPE_WORK:
+                {
+                    TRACE( "executing work callback %p(NULL, %p, %p)\n",
+                           object->u.work.callback, object->userdata, object );
+                    object->u.work.callback( NULL, object->userdata, (TP_WORK *)object );
+                    TRACE( "callback %p returned\n", object->u.work.callback );
+                    break;
+                }
+
                 default:
                     assert(0);
                     break;
@@ -1641,6 +1662,49 @@ NTSTATUS WINAPI TpAllocPool( TP_POOL **out, PVOID reserved )
 }
 
 /***********************************************************************
+ *           TpAllocWork    (NTDLL.@)
+ */
+NTSTATUS WINAPI TpAllocWork( TP_WORK **out, PTP_WORK_CALLBACK callback, PVOID userdata,
+                             TP_CALLBACK_ENVIRON *environment )
+{
+    struct threadpool_object *object;
+    struct threadpool *pool;
+    NTSTATUS status;
+
+    TRACE( "%p %p %p %p\n", out, callback, userdata, environment );
+
+    object = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*object) );
+    if (!object)
+        return STATUS_NO_MEMORY;
+
+    status = tp_threadpool_lock( &pool, environment );
+    if (status)
+    {
+        RtlFreeHeap( GetProcessHeap(), 0, object );
+        return status;
+    }
+
+    object->type = TP_OBJECT_TYPE_WORK;
+    object->u.work.callback = callback;
+    tp_object_initialize( object, pool, userdata, environment );
+
+    *out = (TP_WORK *)object;
+    return STATUS_SUCCESS;
+}
+
+/***********************************************************************
+ *           TpPostWork    (NTDLL.@)
+ */
+VOID WINAPI TpPostWork( TP_WORK *work )
+{
+    struct threadpool_object *this = impl_from_TP_WORK( work );
+
+    TRACE( "%p\n", work );
+
+    tp_object_submit( this );
+}
+
+/***********************************************************************
  *           TpReleaseCleanupGroup    (NTDLL.@)
  */
 VOID WINAPI TpReleaseCleanupGroup( TP_CLEANUP_GROUP *group )
@@ -1728,6 +1792,19 @@ VOID WINAPI TpReleasePool( TP_POOL *pool )
 }
 
 /***********************************************************************
+ *           TpReleaseWork    (NTDLL.@)
+ */
+VOID WINAPI TpReleaseWork( TP_WORK *work )
+{
+    struct threadpool_object *this = impl_from_TP_WORK( work );
+
+    TRACE( "%p\n", work );
+
+    tp_object_shutdown( this );
+    tp_object_release( this );
+}
+
+/***********************************************************************
  *           TpSetPoolMaxThreads    (NTDLL.@)
  */
 VOID WINAPI TpSetPoolMaxThreads( TP_POOL *pool, DWORD maximum )
@@ -1806,3 +1883,17 @@ NTSTATUS WINAPI TpSimpleTryPost( PTP_SIMPLE_CALLBACK callback, PVOID userdata,
 
     return STATUS_SUCCESS;
 }
+
+/***********************************************************************
+ *           TpWaitForWork    (NTDLL.@)
+ */
+VOID WINAPI TpWaitForWork( TP_WORK *work, BOOL cancel_pending )
+{
+    struct threadpool_object *this = impl_from_TP_WORK( work );
+
+    TRACE( "%p %u\n", work, cancel_pending );
+
+    if (cancel_pending)
+        tp_object_cancel( this );
+    tp_object_wait( this );
+}




More information about the wine-cvs mailing list