From e4c38f6bad3df50c71eb9b05a03d38732a854de3 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Wed, 1 Jul 2015 02:57:57 +0200 Subject: [PATCH] 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 f889b0455a5..4b5ece5ea6b 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 2e8568c81ca..da41ba01f9d 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; @@ -1640,6 +1661,49 @@ NTSTATUS WINAPI TpAllocPool( TP_POOL **out, PVOID reserved ) return tp_threadpool_alloc( (struct threadpool **)out ); } +/*********************************************************************** + * 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.@) */ @@ -1727,6 +1791,19 @@ VOID WINAPI TpReleasePool( TP_POOL *pool ) tp_threadpool_release( this ); } +/*********************************************************************** + * 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.@) */ @@ -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 ); +}