From 16aad8a55fa33f385cd12c96b1fdd4de5bf00a38 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Wed, 1 Jul 2015 17:09:18 +0200 Subject: [PATCH] Rebase against 7a3c9889e38ede659230a66a167b82c024f0dc85. --- debian/changelog | 2 + ...-for-threadpool-group-cancel-callba.patch} | 47 +- ...TpSimpleTryPost-and-basic-threadpool.patch | 448 ------------------ ...-for-threadpool-finalization-callba.patch} | 18 +- ...lement-TpSetPool-Min-Max-Threads.-v2.patch | 72 --- ...hreadpool-RaceDll-environment-varia.patch} | 30 +- ...t-threadpool-cleanup-group-functions.patch | 382 --------------- ...pCallbackMayRunLong-and-instance-st.patch} | 138 +++--- ...tests-for-TpAllocCleanupGroup-and-re.patch | 102 ---- ...ll-Implement-TpDisassociateCallback.patch} | 87 ++-- ...ement-threadpool-work-item-functions.patch | 178 ------- ...arious-TpCallback-OnCompletion-func.patch} | 188 +++----- ...basic-tests-for-threadpool-work-item.patch | 108 ----- ...ng-threadpool-functions-to-specfile.patch} | 10 +- ...threadpool-scheduler-tests-for-work-.patch | 132 ------ ...t-threadpool-timer-functions.-rev-2.patch} | 102 ++-- ...d-tests-for-Tp-threadpool-functions.patch} | 6 +- ...various-threadpool-functions-to-ntd.patch} | 26 +- ...l-Implement-threadpool-wait-objects.patch} | 144 +++--- ...d-tests-for-threadpool-wait-objects.patch} | 6 +- ...-threadpool-wait-functions-to-ntdll.patch} | 16 +- patches/patchinstall.sh | 42 +- 22 files changed, 390 insertions(+), 1894 deletions(-) rename patches/ntdll-Vista_Threadpool/{0008-ntdll-Add-support-for-threadpool-group-cancel-callba.patch => 0001-ntdll-Add-support-for-threadpool-group-cancel-callba.patch} (71%) delete mode 100644 patches/ntdll-Vista_Threadpool/0001-ntdll-Implement-TpSimpleTryPost-and-basic-threadpool.patch rename patches/ntdll-Vista_Threadpool/{0009-ntdll-Add-support-for-threadpool-finalization-callba.patch => 0002-ntdll-Add-support-for-threadpool-finalization-callba.patch} (81%) delete mode 100644 patches/ntdll-Vista_Threadpool/0002-ntdll-Implement-TpSetPool-Min-Max-Threads.-v2.patch rename patches/ntdll-Vista_Threadpool/{0010-ntdll-Implement-threadpool-RaceDll-environment-varia.patch => 0003-ntdll-Implement-threadpool-RaceDll-environment-varia.patch} (67%) delete mode 100644 patches/ntdll-Vista_Threadpool/0003-ntdll-Implement-threadpool-cleanup-group-functions.patch rename patches/ntdll-Vista_Threadpool/{0011-ntdll-Implement-TpCallbackMayRunLong-and-instance-st.patch => 0004-ntdll-Implement-TpCallbackMayRunLong-and-instance-st.patch} (73%) delete mode 100644 patches/ntdll-Vista_Threadpool/0004-ntdll-tests-Add-tests-for-TpAllocCleanupGroup-and-re.patch rename patches/ntdll-Vista_Threadpool/{0012-ntdll-Implement-TpDisassociateCallback.patch => 0005-ntdll-Implement-TpDisassociateCallback.patch} (62%) delete mode 100644 patches/ntdll-Vista_Threadpool/0005-ntdll-Implement-threadpool-work-item-functions.patch rename patches/ntdll-Vista_Threadpool/{0013-ntdll-Implement-various-TpCallback-OnCompletion-func.patch => 0006-ntdll-Implement-various-TpCallback-OnCompletion-func.patch} (51%) delete mode 100644 patches/ntdll-Vista_Threadpool/0006-ntdll-tests-Add-basic-tests-for-threadpool-work-item.patch rename patches/ntdll-Vista_Threadpool/{0014-ntdll-Add-remaining-threadpool-functions-to-specfile.patch => 0007-ntdll-Add-remaining-threadpool-functions-to-specfile.patch} (94%) delete mode 100644 patches/ntdll-Vista_Threadpool/0007-ntdll-tests-Add-threadpool-scheduler-tests-for-work-.patch rename patches/ntdll-Vista_Threadpool/{0015-ntdll-Implement-threadpool-timer-functions.-rev-2.patch => 0008-ntdll-Implement-threadpool-timer-functions.-rev-2.patch} (89%) rename patches/ntdll-Vista_Threadpool/{0016-ntdll-tests-Add-tests-for-Tp-threadpool-functions.patch => 0009-ntdll-tests-Add-tests-for-Tp-threadpool-functions.patch} (99%) rename patches/ntdll-Vista_Threadpool/{0017-kernel32-Forward-various-threadpool-functions-to-ntd.patch => 0010-kernel32-Forward-various-threadpool-functions-to-ntd.patch} (97%) rename patches/ntdll-Vista_Threadpool/{0018-ntdll-Implement-threadpool-wait-objects.patch => 0011-ntdll-Implement-threadpool-wait-objects.patch} (88%) rename patches/ntdll-Vista_Threadpool/{0019-ntdll-tests-Add-tests-for-threadpool-wait-objects.patch => 0012-ntdll-tests-Add-tests-for-threadpool-wait-objects.patch} (99%) rename patches/ntdll-Vista_Threadpool/{0020-kernel32-Forward-threadpool-wait-functions-to-ntdll.patch => 0013-kernel32-Forward-threadpool-wait-functions-to-ntdll.patch} (94%) diff --git a/debian/changelog b/debian/changelog index 77a82c63..f9d21b1b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -3,6 +3,8 @@ wine-staging (1.7.47) UNRELEASED; urgency=low upstream). * Removed patch to initialize *end with NULL on failure in msvcrt.strtod (accepted upstream). + * Partially removed patchset for new Threadpool implementation (accepted + upstream). -- Sebastian Lackner Mon, 29 Jun 2015 19:39:04 +0200 wine-staging (1.7.46) unstable; urgency=low diff --git a/patches/ntdll-Vista_Threadpool/0008-ntdll-Add-support-for-threadpool-group-cancel-callba.patch b/patches/ntdll-Vista_Threadpool/0001-ntdll-Add-support-for-threadpool-group-cancel-callba.patch similarity index 71% rename from patches/ntdll-Vista_Threadpool/0008-ntdll-Add-support-for-threadpool-group-cancel-callba.patch rename to patches/ntdll-Vista_Threadpool/0001-ntdll-Add-support-for-threadpool-group-cancel-callba.patch index be07280d..f1a3364e 100644 --- a/patches/ntdll-Vista_Threadpool/0008-ntdll-Add-support-for-threadpool-group-cancel-callba.patch +++ b/patches/ntdll-Vista_Threadpool/0001-ntdll-Add-support-for-threadpool-group-cancel-callba.patch @@ -1,4 +1,4 @@ -From 624d6ab353109a57dfe0d80053795ef64b6adc3e Mon Sep 17 00:00:00 2001 +From aec44ffb06857ee5c954136e82500e1dcb71f97b Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Wed, 4 Mar 2015 06:57:53 +0100 Subject: ntdll: Add support for threadpool group cancel callback. @@ -8,10 +8,10 @@ Subject: ntdll: Add support for threadpool group cancel callback. 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/dlls/ntdll/threadpool.c b/dlls/ntdll/threadpool.c -index 1989d56..e30d45c 100644 +index da41ba0..93d9b28 100644 --- a/dlls/ntdll/threadpool.c +++ b/dlls/ntdll/threadpool.c -@@ -170,6 +170,7 @@ struct threadpool_object +@@ -171,6 +171,7 @@ struct threadpool_object struct threadpool *pool; struct threadpool_group *group; PVOID userdata; @@ -19,7 +19,7 @@ index 1989d56..e30d45c 100644 /* information about the group, locked via .group->cs */ struct list group_entry; BOOL is_group_member; -@@ -1290,6 +1291,7 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa +@@ -1370,6 +1371,7 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa object->pool = pool; object->group = NULL; object->userdata = userdata; @@ -27,25 +27,25 @@ index 1989d56..e30d45c 100644 memset( &object->group_entry, 0, sizeof(object->group_entry) ); object->is_group_member = FALSE; -@@ -1305,6 +1307,7 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa - FIXME("unsupported environment version %u\n", environment->Version); +@@ -1385,6 +1387,7 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa + FIXME( "unsupported environment version %u\n", environment->Version ); object->group = impl_from_TP_CLEANUP_GROUP( environment->CleanupGroup ); + object->group_cancel_callback = environment->CleanupGroupCancelCallback; - WARN("environment not fully implemented yet\n"); + WARN( "environment not fully implemented yet\n" ); } -@@ -1377,7 +1380,7 @@ out: - RtlLeaveCriticalSection( &pool->cs ); - } - +@@ -1467,7 +1470,7 @@ static void tp_object_submit( struct threadpool_object *object ) + * + * Cancels all currently pending callbacks for a specific object. + */ -static void tp_object_cancel( struct threadpool_object *object ) +static void tp_object_cancel( struct threadpool_object *object, BOOL group_cancel, PVOID userdata ) { struct threadpool *pool = object->pool; LONG pending_callbacks = 0; -@@ -1394,6 +1397,14 @@ static void tp_object_cancel( struct threadpool_object *object ) - +@@ -1481,6 +1484,14 @@ static void tp_object_cancel( struct threadpool_object *object ) + } RtlLeaveCriticalSection( &pool->cs ); + /* Execute group cancellation callback if defined, and if this was actually a group cancel. */ @@ -56,10 +56,10 @@ index 1989d56..e30d45c 100644 + TRACE( "callback %p returned\n", object->group_cancel_callback ); + } + - /* Release references */ while (pending_callbacks--) tp_object_release( object ); -@@ -1673,7 +1684,7 @@ VOID WINAPI TpReleaseCleanupGroupMembers( TP_CLEANUP_GROUP *group, BOOL cancel_p + } +@@ -1766,7 +1777,7 @@ VOID WINAPI TpReleaseCleanupGroupMembers( TP_CLEANUP_GROUP *group, BOOL cancel_p { LIST_FOR_EACH_ENTRY( object, &members, struct threadpool_object, group_entry ) { @@ -68,15 +68,14 @@ index 1989d56..e30d45c 100644 } } -@@ -1791,7 +1802,7 @@ VOID WINAPI TpWaitForWork( TP_WORK *work, BOOL cancel_pending ) - if (this) - { - if (cancel_pending) -- tp_object_cancel( this ); -+ tp_object_cancel( this, FALSE, NULL ); - tp_object_wait( this ); - } +@@ -1894,6 +1905,6 @@ VOID WINAPI TpWaitForWork( TP_WORK *work, BOOL cancel_pending ) + TRACE( "%p %u\n", work, cancel_pending ); + + if (cancel_pending) +- tp_object_cancel( this ); ++ tp_object_cancel( this, FALSE, NULL ); + tp_object_wait( this ); } -- -2.3.3 +2.4.4 diff --git a/patches/ntdll-Vista_Threadpool/0001-ntdll-Implement-TpSimpleTryPost-and-basic-threadpool.patch b/patches/ntdll-Vista_Threadpool/0001-ntdll-Implement-TpSimpleTryPost-and-basic-threadpool.patch deleted file mode 100644 index 15d78f2d..00000000 --- a/patches/ntdll-Vista_Threadpool/0001-ntdll-Implement-TpSimpleTryPost-and-basic-threadpool.patch +++ /dev/null @@ -1,448 +0,0 @@ -From f8c57c8ed3616f53bbed2d794f1e858ea5051f22 Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Tue, 24 Feb 2015 05:42:07 +0100 -Subject: ntdll: Implement TpSimpleTryPost and basic threadpool infrastructure. - ---- - dlls/ntdll/ntdll.spec | 3 + - dlls/ntdll/tests/threadpool.c | 3 +- - dlls/ntdll/threadpool.c | 370 ++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 375 insertions(+), 1 deletion(-) - -diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec -index 28165ef..cd6b97c 100644 ---- a/dlls/ntdll/ntdll.spec -+++ b/dlls/ntdll/ntdll.spec -@@ -968,6 +968,9 @@ - @ stdcall RtlxOemStringToUnicodeSize(ptr) RtlOemStringToUnicodeSize - @ stdcall RtlxUnicodeStringToAnsiSize(ptr) RtlUnicodeStringToAnsiSize - @ stdcall RtlxUnicodeStringToOemSize(ptr) RtlUnicodeStringToOemSize -+@ stdcall TpAllocPool(ptr ptr) -+@ stdcall TpReleasePool(ptr) -+@ stdcall TpSimpleTryPost(ptr ptr ptr) - @ stdcall -ret64 VerSetConditionMask(int64 long long) - @ stdcall WinSqmIsOptedIn() - @ stdcall ZwAcceptConnectPort(ptr long ptr long long ptr) NtAcceptConnectPort -diff --git a/dlls/ntdll/tests/threadpool.c b/dlls/ntdll/tests/threadpool.c -index 2e31b34..6f164e9 100644 ---- a/dlls/ntdll/tests/threadpool.c -+++ b/dlls/ntdll/tests/threadpool.c -@@ -48,7 +48,7 @@ static BOOL init_threadpool(void) - - if (!pTpAllocPool) - { -- skip("Threadpool functions not supported, skipping tests\n"); -+ win_skip("Threadpool functions not supported, skipping tests\n"); - return FALSE; - } - -@@ -105,6 +105,7 @@ static void test_tp_simple(void) - environment.Version = 9999; - environment.Pool = pool; - status = pTpSimpleTryPost(simple_cb, semaphore, &environment); -+ todo_wine - ok(status == STATUS_INVALID_PARAMETER || broken(!status) /* Vista/2008 */, - "TpSimpleTryPost unexpectedly returned status %x\n", status); - if (!status) -diff --git a/dlls/ntdll/threadpool.c b/dlls/ntdll/threadpool.c -index 513c13d..cc5f8e9 100644 ---- a/dlls/ntdll/threadpool.c -+++ b/dlls/ntdll/threadpool.c -@@ -2,6 +2,7 @@ - * Thread pooling - * - * Copyright (c) 2006 Robert Shearman -+ * Copyright (c) 2014-2015 Sebastian Lackner - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public -@@ -37,6 +38,10 @@ - - WINE_DEFAULT_DEBUG_CHANNEL(threadpool); - -+/* -+ * Old thread pooling API -+ */ -+ - #define OLD_WORKER_TIMEOUT 30000 /* 30 seconds */ - #define EXPIRE_NEVER (~(ULONGLONG)0) - #define TIMER_QUEUE_MAGIC 0x516d6954 /* TimQ */ -@@ -127,6 +132,64 @@ struct timer_queue - HANDLE thread; - }; - -+/* -+ * New object-oriented thread pooling API -+ */ -+ -+#define THREADPOOL_WORKER_TIMEOUT 5000 -+ -+/* internal threadpool representation */ -+struct threadpool -+{ -+ LONG refcount; -+ BOOL shutdown; -+ CRITICAL_SECTION cs; -+ /* pool of work items, locked via .cs */ -+ struct list pool; -+ RTL_CONDITION_VARIABLE update_event; -+ /* information about worker threads, locked via .cs */ -+ int max_workers; -+ int min_workers; -+ int num_workers; -+ int num_busy_workers; -+}; -+ -+enum threadpool_objtype -+{ -+ TP_OBJECT_TYPE_SIMPLE -+}; -+ -+/* internal threadpool object representation */ -+struct threadpool_object -+{ -+ LONG refcount; -+ BOOL shutdown; -+ /* read-only information */ -+ enum threadpool_objtype type; -+ struct threadpool *pool; -+ PVOID userdata; -+ /* information about the pool, locked via .pool->cs */ -+ struct list pool_entry; -+ LONG num_pending_callbacks; -+ LONG num_running_callbacks; -+ /* arguments for callback */ -+ union -+ { -+ struct -+ { -+ PTP_SIMPLE_CALLBACK callback; -+ } simple; -+ } u; -+}; -+ -+static inline struct threadpool *impl_from_TP_POOL( TP_POOL *pool ) -+{ -+ return (struct threadpool *)pool; -+} -+ -+static void CALLBACK threadpool_worker_proc( void *param ); -+static struct threadpool *default_threadpool = NULL; -+ - static inline LONG interlocked_inc( PLONG dest ) - { - return interlocked_xchg_add( dest, 1 ) + 1; -@@ -1044,3 +1107,310 @@ NTSTATUS WINAPI RtlDeleteTimer(HANDLE TimerQueue, HANDLE Timer, - - return status; - } -+ -+/* allocate a new threadpool (with at least one worker thread) */ -+static NTSTATUS tp_threadpool_alloc( struct threadpool **out ) -+{ -+ struct threadpool *pool; -+ NTSTATUS status; -+ HANDLE thread; -+ -+ pool = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*pool) ); -+ if (!pool) -+ return STATUS_NO_MEMORY; -+ -+ pool->refcount = 2; /* this thread + worker proc */ -+ pool->shutdown = FALSE; -+ -+ RtlInitializeCriticalSection( &pool->cs ); -+ pool->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": threadpool.cs"); -+ -+ list_init( &pool->pool ); -+ RtlInitializeConditionVariable( &pool->update_event ); -+ -+ pool->max_workers = 500; -+ pool->min_workers = 1; -+ pool->num_workers = 1; -+ pool->num_busy_workers = 0; -+ -+ status = RtlCreateUserThread( GetCurrentProcess(), NULL, FALSE, NULL, 0, 0, -+ threadpool_worker_proc, pool, &thread, NULL ); -+ if (status != STATUS_SUCCESS) -+ { -+ pool->cs.DebugInfo->Spare[0] = 0; -+ RtlDeleteCriticalSection( &pool->cs ); -+ RtlFreeHeap( GetProcessHeap(), 0, pool ); -+ return status; -+ } -+ NtClose( thread ); -+ -+ TRACE("allocated threadpool %p\n", pool); -+ -+ *out = pool; -+ return STATUS_SUCCESS; -+} -+ -+/* shutdown all threads of the threadpool */ -+static void tp_threadpool_shutdown( struct threadpool *pool ) -+{ -+ assert( pool != default_threadpool ); -+ -+ pool->shutdown = TRUE; -+ RtlWakeAllConditionVariable( &pool->update_event ); -+} -+ -+/* release a reference to a threadpool */ -+static BOOL tp_threadpool_release( struct threadpool *pool ) -+{ -+ if (interlocked_dec( &pool->refcount )) -+ return FALSE; -+ -+ TRACE("destroying threadpool %p\n", pool); -+ -+ assert( pool->shutdown ); -+ assert( list_empty( &pool->pool ) ); -+ -+ pool->cs.DebugInfo->Spare[0] = 0; -+ RtlDeleteCriticalSection( &pool->cs ); -+ -+ RtlFreeHeap( GetProcessHeap(), 0, pool ); -+ return TRUE; -+} -+ -+/* returns the threadpool based on the environment structure */ -+static struct threadpool *get_threadpool( TP_CALLBACK_ENVIRON *environment ) -+{ -+ struct threadpool *pool; -+ -+ if (environment) -+ { -+ pool = (struct threadpool *)environment->Pool; -+ if (pool) return pool; -+ } -+ -+ if (!default_threadpool) -+ { -+ if (tp_threadpool_alloc( &pool ) != STATUS_SUCCESS) -+ return NULL; -+ -+ if (interlocked_cmpxchg_ptr( (void *)&default_threadpool, pool, NULL ) != NULL) -+ { -+ tp_threadpool_shutdown( pool ); -+ tp_threadpool_release( pool ); -+ } -+ } -+ -+ return default_threadpool; -+} -+ -+/* initializes a new threadpool object */ -+static void tp_object_initialize( struct threadpool_object *object, struct threadpool *pool, -+ PVOID userdata, TP_CALLBACK_ENVIRON *environment ) -+{ -+ object->refcount = 1; -+ object->shutdown = FALSE; -+ -+ object->pool = pool; -+ object->userdata = userdata; -+ -+ memset( &object->pool_entry, 0, sizeof(object->pool_entry) ); -+ object->num_pending_callbacks = 0; -+ object->num_running_callbacks = 0; -+ -+ if (environment) -+ FIXME("environment not implemented yet\n"); -+ -+ /* Increase reference-count on the pool */ -+ interlocked_inc( &pool->refcount ); -+ -+ TRACE("allocated object %p of type %u\n", object, object->type); -+} -+ -+/* submits an object to a threadpool */ -+static void tp_object_submit( struct threadpool_object *object ) -+{ -+ struct threadpool *pool = object->pool; -+ -+ assert( !object->shutdown ); -+ assert( !pool->shutdown ); -+ -+ RtlEnterCriticalSection( &pool->cs ); -+ -+ /* Start new worker threads if required (and allowed) */ -+ if (pool->num_busy_workers >= pool->num_workers && pool->num_workers < pool->max_workers) -+ { -+ NTSTATUS status; -+ HANDLE thread; -+ -+ status = RtlCreateUserThread( GetCurrentProcess(), NULL, FALSE, NULL, 0, 0, -+ threadpool_worker_proc, pool, &thread, NULL ); -+ if (status == STATUS_SUCCESS) -+ { -+ interlocked_inc( &pool->refcount ); -+ pool->num_workers++; -+ NtClose( thread ); -+ goto out; -+ } -+ } -+ -+ assert( pool->num_workers > 0 ); -+ RtlWakeConditionVariable( &pool->update_event ); -+ -+out: -+ /* Queue work item into pool and increment refcount */ -+ interlocked_inc( &object->refcount ); -+ if (!object->num_pending_callbacks++) -+ list_add_tail( &pool->pool, &object->pool_entry ); -+ -+ RtlLeaveCriticalSection( &pool->cs ); -+} -+ -+/* mark an object as 'shutdown', submitting is no longer possible */ -+static void tp_object_shutdown( struct threadpool_object *object ) -+{ -+ object->shutdown = TRUE; -+} -+ -+/* release a reference to a threadpool object */ -+static BOOL tp_object_release( struct threadpool_object *object ) -+{ -+ if (interlocked_dec( &object->refcount )) -+ return FALSE; -+ -+ TRACE("destroying object %p of type %u\n", object, object->type); -+ -+ assert( object->shutdown ); -+ assert( !object->num_pending_callbacks ); -+ assert( !object->num_running_callbacks ); -+ -+ /* release reference to threadpool */ -+ tp_threadpool_release( object->pool ); -+ -+ RtlFreeHeap( GetProcessHeap(), 0, object ); -+ return TRUE; -+} -+ -+/* threadpool worker function */ -+static void CALLBACK threadpool_worker_proc( void *param ) -+{ -+ struct threadpool *pool = param; -+ LARGE_INTEGER timeout; -+ struct list *ptr; -+ -+ RtlEnterCriticalSection( &pool->cs ); -+ for (;;) -+ { -+ while ((ptr = list_head( &pool->pool ))) -+ { -+ struct threadpool_object *object = LIST_ENTRY( ptr, struct threadpool_object, pool_entry ); -+ assert( object->num_pending_callbacks > 0 ); -+ -+ /* If further pending callbacks are queued, move the work item to -+ * the end of the pool list. Otherwise remove it from the pool. */ -+ list_remove( &object->pool_entry ); -+ if (--object->num_pending_callbacks) -+ list_add_tail( &pool->pool, &object->pool_entry ); -+ -+ /* Leave critical section and do the actual callback. */ -+ object->num_running_callbacks++; -+ pool->num_busy_workers++; -+ RtlLeaveCriticalSection( &pool->cs ); -+ -+ switch (object->type) -+ { -+ case TP_OBJECT_TYPE_SIMPLE: -+ { -+ TRACE( "executing simple callback %p(NULL, %p)\n", -+ object->u.simple.callback, object->userdata ); -+ object->u.simple.callback( NULL, object->userdata ); -+ TRACE( "callback %p returned\n", object->u.simple.callback ); -+ break; -+ } -+ -+ default: -+ assert(0); -+ break; -+ } -+ -+ RtlEnterCriticalSection( &pool->cs ); -+ pool->num_busy_workers--; -+ object->num_running_callbacks--; -+ tp_object_release( object ); -+ } -+ -+ /* Shutdown worker thread if requested. */ -+ if (pool->shutdown) -+ break; -+ -+ /* Wait for new tasks or until timeout expires. Never terminate the last worker. */ -+ timeout.QuadPart = (ULONGLONG)THREADPOOL_WORKER_TIMEOUT * -10000; -+ if (RtlSleepConditionVariableCS( &pool->update_event, &pool->cs, &timeout ) == STATUS_TIMEOUT && -+ !list_head( &pool->pool ) && pool->num_workers > 1) -+ { -+ break; -+ } -+ } -+ pool->num_workers--; -+ RtlLeaveCriticalSection( &pool->cs ); -+ tp_threadpool_release( pool ); -+} -+ -+/*********************************************************************** -+ * TpAllocPool (NTDLL.@) -+ */ -+NTSTATUS WINAPI TpAllocPool( TP_POOL **out, PVOID reserved ) -+{ -+ TRACE("%p %p\n", out, reserved); -+ -+ if (reserved) -+ FIXME("reserved argument is nonzero (%p)", reserved); -+ -+ if (!out) -+ return STATUS_ACCESS_VIOLATION; -+ -+ return tp_threadpool_alloc( (struct threadpool **)out ); -+} -+ -+/*********************************************************************** -+ * TpReleasePool (NTDLL.@) -+ */ -+VOID WINAPI TpReleasePool( TP_POOL *pool ) -+{ -+ struct threadpool *this = impl_from_TP_POOL( pool ); -+ TRACE("%p\n", pool); -+ -+ if (this) -+ { -+ tp_threadpool_shutdown( this ); -+ tp_threadpool_release( this ); -+ } -+} -+ -+/*********************************************************************** -+ * TpSimpleTryPost (NTDLL.@) -+ */ -+NTSTATUS WINAPI TpSimpleTryPost( PTP_SIMPLE_CALLBACK callback, PVOID userdata, -+ TP_CALLBACK_ENVIRON *environment ) -+{ -+ struct threadpool_object *object; -+ struct threadpool *pool; -+ -+ TRACE("%p %p %p\n", callback, userdata, environment); -+ -+ if (!(pool = get_threadpool( environment ))) -+ return STATUS_NO_MEMORY; -+ -+ object = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*object) ); -+ if (!object) -+ return STATUS_NO_MEMORY; -+ -+ object->type = TP_OBJECT_TYPE_SIMPLE; -+ object->u.simple.callback = callback; -+ tp_object_initialize( object, pool, userdata, environment ); -+ -+ tp_object_submit( object ); -+ -+ tp_object_shutdown( object ); -+ tp_object_release( object ); -+ return STATUS_SUCCESS; -+} --- -2.3.5 - diff --git a/patches/ntdll-Vista_Threadpool/0009-ntdll-Add-support-for-threadpool-finalization-callba.patch b/patches/ntdll-Vista_Threadpool/0002-ntdll-Add-support-for-threadpool-finalization-callba.patch similarity index 81% rename from patches/ntdll-Vista_Threadpool/0009-ntdll-Add-support-for-threadpool-finalization-callba.patch rename to patches/ntdll-Vista_Threadpool/0002-ntdll-Add-support-for-threadpool-finalization-callba.patch index 68a14895..6d96c466 100644 --- a/patches/ntdll-Vista_Threadpool/0009-ntdll-Add-support-for-threadpool-finalization-callba.patch +++ b/patches/ntdll-Vista_Threadpool/0002-ntdll-Add-support-for-threadpool-finalization-callba.patch @@ -1,4 +1,4 @@ -From d92b2f79160613f6d2f258cbf98624fee30844a8 Mon Sep 17 00:00:00 2001 +From 9a973853b87ff70fac8fbc42308300a861dc39de Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Wed, 4 Mar 2015 07:03:15 +0100 Subject: ntdll: Add support for threadpool finalization callback. @@ -8,10 +8,10 @@ Subject: ntdll: Add support for threadpool finalization callback. 1 file changed, 12 insertions(+) diff --git a/dlls/ntdll/threadpool.c b/dlls/ntdll/threadpool.c -index e30d45c..927d31c 100644 +index 93d9b28..0133e66 100644 --- a/dlls/ntdll/threadpool.c +++ b/dlls/ntdll/threadpool.c -@@ -171,6 +171,7 @@ struct threadpool_object +@@ -172,6 +172,7 @@ struct threadpool_object struct threadpool_group *group; PVOID userdata; PTP_CLEANUP_GROUP_CANCEL_CALLBACK group_cancel_callback; @@ -19,7 +19,7 @@ index e30d45c..927d31c 100644 /* information about the group, locked via .group->cs */ struct list group_entry; BOOL is_group_member; -@@ -1292,6 +1293,7 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa +@@ -1372,6 +1373,7 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa object->group = NULL; object->userdata = userdata; object->group_cancel_callback = NULL; @@ -27,19 +27,19 @@ index e30d45c..927d31c 100644 memset( &object->group_entry, 0, sizeof(object->group_entry) ); object->is_group_member = FALSE; -@@ -1308,6 +1310,7 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa +@@ -1388,6 +1390,7 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa object->group = impl_from_TP_CLEANUP_GROUP( environment->CleanupGroup ); object->group_cancel_callback = environment->CleanupGroupCancelCallback; + object->finalization_callback = environment->FinalizationCallback; - WARN("environment not fully implemented yet\n"); + WARN( "environment not fully implemented yet\n" ); } -@@ -1515,6 +1518,15 @@ static void CALLBACK threadpool_worker_proc( void *param ) +@@ -1616,6 +1619,15 @@ static void CALLBACK threadpool_worker_proc( void *param ) break; } -+ /* Execute finalization callback */ ++ /* Execute finalization callback. */ + if (object->finalization_callback) + { + TRACE( "executing finalization callback %p(NULL, %p)\n", @@ -52,5 +52,5 @@ index e30d45c..927d31c 100644 pool->num_busy_workers--; object->num_running_callbacks--; -- -2.3.3 +2.4.4 diff --git a/patches/ntdll-Vista_Threadpool/0002-ntdll-Implement-TpSetPool-Min-Max-Threads.-v2.patch b/patches/ntdll-Vista_Threadpool/0002-ntdll-Implement-TpSetPool-Min-Max-Threads.-v2.patch deleted file mode 100644 index c7908b68..00000000 --- a/patches/ntdll-Vista_Threadpool/0002-ntdll-Implement-TpSetPool-Min-Max-Threads.-v2.patch +++ /dev/null @@ -1,72 +0,0 @@ -From c362c574aa6611f80c6965ea66cbfab33e421d0f Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Wed, 4 Mar 2015 00:16:20 +0100 -Subject: ntdll: Implement TpSetPool[Min|Max]Threads. (v2) - ---- - dlls/ntdll/ntdll.spec | 2 ++ - dlls/ntdll/threadpool.c | 35 +++++++++++++++++++++++++++++++++++ - 2 files changed, 37 insertions(+) - -diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec -index cd6b97c..f755286 100644 ---- a/dlls/ntdll/ntdll.spec -+++ b/dlls/ntdll/ntdll.spec -@@ -970,6 +970,8 @@ - @ stdcall RtlxUnicodeStringToOemSize(ptr) RtlUnicodeStringToOemSize - @ stdcall TpAllocPool(ptr ptr) - @ stdcall TpReleasePool(ptr) -+@ stdcall TpSetPoolMaxThreads(ptr long) -+@ stdcall TpSetPoolMinThreads(ptr long) - @ stdcall TpSimpleTryPost(ptr ptr ptr) - @ stdcall -ret64 VerSetConditionMask(int64 long long) - @ stdcall WinSqmIsOptedIn() -diff --git a/dlls/ntdll/threadpool.c b/dlls/ntdll/threadpool.c -index cc5f8e9..cb2dcdd 100644 ---- a/dlls/ntdll/threadpool.c -+++ b/dlls/ntdll/threadpool.c -@@ -1387,6 +1387,41 @@ VOID WINAPI TpReleasePool( TP_POOL *pool ) - } - - /*********************************************************************** -+ * TpSetPoolMaxThreads (NTDLL.@) -+ */ -+VOID WINAPI TpSetPoolMaxThreads( TP_POOL *pool, DWORD maximum ) -+{ -+ struct threadpool *this = impl_from_TP_POOL( pool ); -+ TRACE("%p %d\n", pool, maximum); -+ -+ if (this) -+ { -+ RtlEnterCriticalSection( &this->cs ); -+ this->max_workers = max( maximum, 1 ); -+ this->min_workers = min( this->min_workers, this->max_workers ); -+ RtlLeaveCriticalSection( &this->cs ); -+ } -+} -+ -+/*********************************************************************** -+ * TpSetPoolMinThreads (NTDLL.@) -+ */ -+BOOL WINAPI TpSetPoolMinThreads( TP_POOL *pool, DWORD minimum ) -+{ -+ struct threadpool *this = impl_from_TP_POOL( pool ); -+ FIXME("%p %d: semi-stub\n", pool, minimum); -+ -+ if (this) -+ { -+ RtlEnterCriticalSection( &this->cs ); -+ this->min_workers = max( minimum, 1 ); -+ this->max_workers = max( this->min_workers, this->max_workers ); -+ RtlLeaveCriticalSection( &this->cs ); -+ } -+ return TRUE; -+} -+ -+/*********************************************************************** - * TpSimpleTryPost (NTDLL.@) - */ - NTSTATUS WINAPI TpSimpleTryPost( PTP_SIMPLE_CALLBACK callback, PVOID userdata, --- -2.3.5 - diff --git a/patches/ntdll-Vista_Threadpool/0010-ntdll-Implement-threadpool-RaceDll-environment-varia.patch b/patches/ntdll-Vista_Threadpool/0003-ntdll-Implement-threadpool-RaceDll-environment-varia.patch similarity index 67% rename from patches/ntdll-Vista_Threadpool/0010-ntdll-Implement-threadpool-RaceDll-environment-varia.patch rename to patches/ntdll-Vista_Threadpool/0003-ntdll-Implement-threadpool-RaceDll-environment-varia.patch index e8430018..5c51c0a2 100644 --- a/patches/ntdll-Vista_Threadpool/0010-ntdll-Implement-threadpool-RaceDll-environment-varia.patch +++ b/patches/ntdll-Vista_Threadpool/0003-ntdll-Implement-threadpool-RaceDll-environment-varia.patch @@ -1,17 +1,17 @@ -From a2fdd577db91938092d4c38d16a469ddf46189fb Mon Sep 17 00:00:00 2001 +From 6bc11921f0b13e7029d5f42f3fd9d2c88891cd41 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Wed, 4 Mar 2015 07:07:07 +0100 Subject: ntdll: Implement threadpool RaceDll environment variable. --- - dlls/ntdll/threadpool.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) + dlls/ntdll/threadpool.c | 9 +++++++++ + 1 file changed, 9 insertions(+) diff --git a/dlls/ntdll/threadpool.c b/dlls/ntdll/threadpool.c -index 927d31c..47f6f6f 100644 +index 0133e66..4ae81b0 100644 --- a/dlls/ntdll/threadpool.c +++ b/dlls/ntdll/threadpool.c -@@ -172,6 +172,7 @@ struct threadpool_object +@@ -173,6 +173,7 @@ struct threadpool_object PVOID userdata; PTP_CLEANUP_GROUP_CANCEL_CALLBACK group_cancel_callback; PTP_SIMPLE_CALLBACK finalization_callback; @@ -19,7 +19,7 @@ index 927d31c..47f6f6f 100644 /* information about the group, locked via .group->cs */ struct list group_entry; BOOL is_group_member; -@@ -1294,6 +1295,7 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa +@@ -1374,6 +1375,7 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa object->userdata = userdata; object->group_cancel_callback = NULL; object->finalization_callback = NULL; @@ -27,27 +27,25 @@ index 927d31c..47f6f6f 100644 memset( &object->group_entry, 0, sizeof(object->group_entry) ); object->is_group_member = FALSE; -@@ -1311,10 +1313,15 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa +@@ -1391,10 +1393,14 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa object->group = impl_from_TP_CLEANUP_GROUP( environment->CleanupGroup ); object->group_cancel_callback = environment->CleanupGroupCancelCallback; object->finalization_callback = environment->FinalizationCallback; + object->race_dll = environment->RaceDll; - WARN("environment not fully implemented yet\n"); + WARN( "environment not fully implemented yet\n" ); } -+ /* Increase dll refcount */ + if (object->race_dll) + LdrAddRefDll( 0, object->race_dll ); + - /* Increase reference-count on the pool */ - interlocked_inc( &pool->refcount ); + TRACE( "allocated object %p of type %u\n", object, object->type ); -@@ -1463,6 +1470,10 @@ static BOOL tp_object_release( struct threadpool_object *object ) - /* release reference to threadpool */ - tp_threadpool_release( object->pool ); + /* For simple callbacks we have to run tp_object_submit before adding this object +@@ -1560,6 +1566,9 @@ static BOOL tp_object_release( struct threadpool_object *object ) + + tp_threadpool_unlock( object->pool ); -+ /* release reference to library */ + if (object->race_dll) + LdrUnloadDll( object->race_dll ); + @@ -55,5 +53,5 @@ index 927d31c..47f6f6f 100644 return TRUE; } -- -2.3.3 +2.4.4 diff --git a/patches/ntdll-Vista_Threadpool/0003-ntdll-Implement-threadpool-cleanup-group-functions.patch b/patches/ntdll-Vista_Threadpool/0003-ntdll-Implement-threadpool-cleanup-group-functions.patch deleted file mode 100644 index 44557e69..00000000 --- a/patches/ntdll-Vista_Threadpool/0003-ntdll-Implement-threadpool-cleanup-group-functions.patch +++ /dev/null @@ -1,382 +0,0 @@ -From 63ebc5c972502aaa60d50b1f6ca54f6a9646fca6 Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Wed, 4 Mar 2015 00:52:18 +0100 -Subject: ntdll: Implement threadpool cleanup group functions. - ---- - dlls/ntdll/ntdll.spec | 3 + - dlls/ntdll/threadpool.c | 259 +++++++++++++++++++++++++++++++++++++++++++++++- - 2 files changed, 257 insertions(+), 5 deletions(-) - -diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec -index 88d915b..853ca09 100644 ---- a/dlls/ntdll/ntdll.spec -+++ b/dlls/ntdll/ntdll.spec -@@ -968,7 +968,10 @@ - @ stdcall RtlxOemStringToUnicodeSize(ptr) RtlOemStringToUnicodeSize - @ stdcall RtlxUnicodeStringToAnsiSize(ptr) RtlUnicodeStringToAnsiSize - @ stdcall RtlxUnicodeStringToOemSize(ptr) RtlUnicodeStringToOemSize -+@ stdcall TpAllocCleanupGroup(ptr) - @ stdcall TpAllocPool(ptr ptr) -+@ stdcall TpReleaseCleanupGroup(ptr) -+@ stdcall TpReleaseCleanupGroupMembers(ptr long ptr) - @ stdcall TpReleasePool(ptr) - @ stdcall TpSetPoolMaxThreads(ptr long) - @ stdcall TpSetPoolMinThreads(ptr long) -diff --git a/dlls/ntdll/threadpool.c b/dlls/ntdll/threadpool.c -index 16d9209..092fa6f 100644 ---- a/dlls/ntdll/threadpool.c -+++ b/dlls/ntdll/threadpool.c -@@ -167,9 +167,14 @@ struct threadpool_object - /* read-only information */ - enum threadpool_objtype type; - struct threadpool *pool; -+ struct threadpool_group *group; - PVOID userdata; -+ /* information about the group, locked via .group->cs */ -+ struct list group_entry; -+ BOOL is_group_member; - /* information about the pool, locked via .pool->cs */ - struct list pool_entry; -+ RTL_CONDITION_VARIABLE finished_event; - LONG num_pending_callbacks; - LONG num_running_callbacks; - /* arguments for callback */ -@@ -182,12 +187,30 @@ struct threadpool_object - } u; - }; - -+/* internal threadpool group representation */ -+struct threadpool_group -+{ -+ LONG refcount; -+ BOOL shutdown; -+ CRITICAL_SECTION cs; -+ /* list of group members, locked via .cs */ -+ struct list members; -+}; -+ - static inline struct threadpool *impl_from_TP_POOL( TP_POOL *pool ) - { - return (struct threadpool *)pool; - } - -+static inline struct threadpool_group *impl_from_TP_CLEANUP_GROUP( TP_CLEANUP_GROUP *group ) -+{ -+ return (struct threadpool_group *)group; -+} -+ - static void CALLBACK threadpool_worker_proc( void *param ); -+static void tp_object_submit( struct threadpool_object *object ); -+static void tp_object_shutdown( struct threadpool_object *object ); -+static BOOL tp_object_release( struct threadpool_object *object ); - static struct threadpool *default_threadpool = NULL; - - static inline LONG interlocked_inc( PLONG dest ) -@@ -1196,27 +1219,111 @@ static struct threadpool *get_default_threadpool( void ) - return default_threadpool; - } - -+/* allocates a new cleanup group */ -+static NTSTATUS tp_group_alloc( struct threadpool_group **out ) -+{ -+ struct threadpool_group *group; -+ -+ group = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*group) ); -+ if (!group) -+ return STATUS_NO_MEMORY; -+ -+ group->refcount = 1; -+ group->shutdown = FALSE; -+ -+ RtlInitializeCriticalSection( &group->cs ); -+ group->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": threadpool_group.cs"); -+ -+ list_init( &group->members ); -+ -+ TRACE("allocated group %p\n", group); -+ -+ *out = group; -+ return STATUS_SUCCESS; -+} -+ -+/* marks a cleanup group for shutdown */ -+static void tp_group_shutdown( struct threadpool_group *group ) -+{ -+ group->shutdown = TRUE; -+} -+ -+/* releases a reference to a cleanup group */ -+static BOOL tp_group_release( struct threadpool_group *group ) -+{ -+ if (interlocked_dec( &group->refcount )) -+ return FALSE; -+ -+ TRACE("destroying group %p\n", group); -+ -+ assert( group->shutdown ); -+ assert( list_empty( &group->members ) ); -+ -+ group->cs.DebugInfo->Spare[0] = 0; -+ RtlDeleteCriticalSection( &group->cs ); -+ -+ RtlFreeHeap( GetProcessHeap(), 0, group ); -+ return TRUE; -+} -+ - /* initializes a new threadpool object */ - static void tp_object_initialize( struct threadpool_object *object, struct threadpool *pool, - PVOID userdata, TP_CALLBACK_ENVIRON *environment ) - { -+ BOOL simple_cb = (object->type == TP_OBJECT_TYPE_SIMPLE); -+ - object->refcount = 1; - object->shutdown = FALSE; - - object->pool = pool; -+ object->group = NULL; - object->userdata = userdata; - -+ memset( &object->group_entry, 0, sizeof(object->group_entry) ); -+ object->is_group_member = FALSE; -+ - memset( &object->pool_entry, 0, sizeof(object->pool_entry) ); -+ RtlInitializeConditionVariable( &object->finished_event ); - object->num_pending_callbacks = 0; - object->num_running_callbacks = 0; - - if (environment) -- FIXME("environment not implemented yet\n"); -+ { -+ if (environment->Version != 1) -+ FIXME("unsupported environment version %u\n", environment->Version); -+ -+ object->group = impl_from_TP_CLEANUP_GROUP( environment->CleanupGroup ); -+ -+ WARN("environment not fully implemented yet\n"); -+ } - - /* Increase reference-count on the pool */ - interlocked_inc( &pool->refcount ); - - TRACE("allocated object %p of type %u\n", object, object->type); -+ -+ /* For simple callbacks we have to run tp_object_submit before adding this object -+ * to the cleanup group. As soon as the cleanup group members are released ->shutdown -+ * will be set, and tp_object_submit would fail with an assertion. */ -+ if (simple_cb) -+ tp_object_submit( object ); -+ -+ if (object->group) -+ { -+ struct threadpool_group *group = object->group; -+ interlocked_inc( &group->refcount ); -+ -+ RtlEnterCriticalSection( &group->cs ); -+ list_add_tail( &group->members, &object->group_entry ); -+ object->is_group_member = TRUE; -+ RtlLeaveCriticalSection( &group->cs ); -+ } -+ -+ if (simple_cb) -+ { -+ tp_object_shutdown( object ); -+ tp_object_release( object ); -+ } - } - - /* submits an object to a threadpool */ -@@ -1258,6 +1365,41 @@ out: - RtlLeaveCriticalSection( &pool->cs ); - } - -+static void tp_object_cancel( struct threadpool_object *object ) -+{ -+ struct threadpool *pool = object->pool; -+ LONG pending_callbacks = 0; -+ -+ RtlEnterCriticalSection( &pool->cs ); -+ -+ /* Remove the pending callbacks from the pool */ -+ if (object->num_pending_callbacks) -+ { -+ pending_callbacks = object->num_pending_callbacks; -+ object->num_pending_callbacks = 0; -+ list_remove( &object->pool_entry ); -+ } -+ -+ RtlLeaveCriticalSection( &pool->cs ); -+ -+ /* Release references */ -+ while (pending_callbacks--) -+ tp_object_release( object ); -+} -+ -+static void tp_object_wait( struct threadpool_object *object ) -+{ -+ struct threadpool *pool = object->pool; -+ -+ RtlEnterCriticalSection( &pool->cs ); -+ -+ /* Wait until there are no longer pending or running callbacks */ -+ while (object->num_pending_callbacks || object->num_running_callbacks) -+ RtlSleepConditionVariableCS( &object->finished_event, &pool->cs, NULL ); -+ -+ RtlLeaveCriticalSection( &pool->cs ); -+} -+ - /* mark an object as 'shutdown', submitting is no longer possible */ - static void tp_object_shutdown( struct threadpool_object *object ) - { -@@ -1276,6 +1418,22 @@ static BOOL tp_object_release( struct threadpool_object *object ) - assert( !object->num_pending_callbacks ); - assert( !object->num_running_callbacks ); - -+ /* release reference to the group */ -+ if (object->group) -+ { -+ struct threadpool_group *group = object->group; -+ -+ RtlEnterCriticalSection( &group->cs ); -+ if (object->is_group_member) -+ { -+ list_remove( &object->group_entry ); -+ object->is_group_member = FALSE; -+ } -+ RtlLeaveCriticalSection( &group->cs ); -+ -+ tp_group_release( group ); -+ } -+ - /* release reference to threadpool */ - tp_threadpool_release( object->pool ); - -@@ -1328,6 +1486,8 @@ static void CALLBACK threadpool_worker_proc( void *param ) - RtlEnterCriticalSection( &pool->cs ); - pool->num_busy_workers--; - object->num_running_callbacks--; -+ if (!object->num_pending_callbacks && !object->num_running_callbacks) -+ RtlWakeAllConditionVariable( &object->finished_event ); - tp_object_release( object ); - } - -@@ -1348,6 +1508,20 @@ static void CALLBACK threadpool_worker_proc( void *param ) - tp_threadpool_release( pool ); - } - -+ -+/*********************************************************************** -+ * TpAllocCleanupGroup (NTDLL.@) -+ */ -+NTSTATUS WINAPI TpAllocCleanupGroup( TP_CLEANUP_GROUP **out ) -+{ -+ TRACE("%p\n", out); -+ -+ if (!out) -+ return STATUS_ACCESS_VIOLATION; -+ -+ return tp_group_alloc( (struct threadpool_group **)out ); -+} -+ - /*********************************************************************** - * TpAllocPool (NTDLL.@) - */ -@@ -1365,6 +1539,85 @@ NTSTATUS WINAPI TpAllocPool( TP_POOL **out, PVOID reserved ) - } - - /*********************************************************************** -+ * TpReleaseCleanupGroup (NTDLL.@) -+ */ -+VOID WINAPI TpReleaseCleanupGroup( TP_CLEANUP_GROUP *group ) -+{ -+ struct threadpool_group *this = impl_from_TP_CLEANUP_GROUP( group ); -+ TRACE("%p\n", group); -+ -+ if (this) -+ { -+ tp_group_shutdown( this ); -+ tp_group_release( this ); -+ } -+} -+ -+/*********************************************************************** -+ * TpReleaseCleanupGroupMembers (NTDLL.@) -+ */ -+VOID WINAPI TpReleaseCleanupGroupMembers( TP_CLEANUP_GROUP *group, BOOL cancel_pending, PVOID userdata ) -+{ -+ struct threadpool_group *this = impl_from_TP_CLEANUP_GROUP( group ); -+ struct threadpool_object *object, *next; -+ struct list members; -+ -+ TRACE("%p %d %p\n", group, cancel_pending, userdata); -+ -+ if (!this) -+ return; -+ -+ RtlEnterCriticalSection( &this->cs ); -+ -+ /* Unset group, increase references, and mark objects for shutdown */ -+ LIST_FOR_EACH_ENTRY_SAFE( object, next, &this->members, struct threadpool_object, group_entry ) -+ { -+ assert( object->group == this ); -+ assert( object->is_group_member ); -+ -+ /* Simple callbacks are very special. The user doesn't hold any reference, so -+ * they would be released too early. Add one additional temporary reference. */ -+ if (object->type == TP_OBJECT_TYPE_SIMPLE) -+ { -+ if (interlocked_inc( &object->refcount ) == 1) -+ { -+ /* Object is basically already destroyed, but group reference -+ * was not deleted yet. We can safely ignore this object. */ -+ interlocked_dec( &object->refcount ); -+ list_remove( &object->group_entry ); -+ object->is_group_member = FALSE; -+ continue; -+ } -+ } -+ -+ object->is_group_member = FALSE; -+ tp_object_shutdown( object ); -+ } -+ -+ /* Move members to a local list */ -+ list_init( &members ); -+ list_move_tail( &members, &this->members ); -+ -+ RtlLeaveCriticalSection( &this->cs ); -+ -+ /* Cancel pending callbacks if requested */ -+ if (cancel_pending) -+ { -+ LIST_FOR_EACH_ENTRY( object, &members, struct threadpool_object, group_entry ) -+ { -+ tp_object_cancel( object ); -+ } -+ } -+ -+ /* Wait for remaining callbacks to finish */ -+ LIST_FOR_EACH_ENTRY_SAFE( object, next, &members, struct threadpool_object, group_entry ) -+ { -+ tp_object_wait( object ); -+ tp_object_release( object ); -+ } -+} -+ -+/*********************************************************************** - * TpReleasePool (NTDLL.@) - */ - VOID WINAPI TpReleasePool( TP_POOL *pool ) -@@ -1441,9 +1694,5 @@ NTSTATUS WINAPI TpSimpleTryPost( PTP_SIMPLE_CALLBACK callback, PVOID userdata, - object->u.simple.callback = callback; - tp_object_initialize( object, pool, userdata, environment ); - -- tp_object_submit( object ); -- -- tp_object_shutdown( object ); -- tp_object_release( object ); - return STATUS_SUCCESS; - } --- -2.3.3 - diff --git a/patches/ntdll-Vista_Threadpool/0011-ntdll-Implement-TpCallbackMayRunLong-and-instance-st.patch b/patches/ntdll-Vista_Threadpool/0004-ntdll-Implement-TpCallbackMayRunLong-and-instance-st.patch similarity index 73% rename from patches/ntdll-Vista_Threadpool/0011-ntdll-Implement-TpCallbackMayRunLong-and-instance-st.patch rename to patches/ntdll-Vista_Threadpool/0004-ntdll-Implement-TpCallbackMayRunLong-and-instance-st.patch index bab7671f..c2bfca19 100644 --- a/patches/ntdll-Vista_Threadpool/0011-ntdll-Implement-TpCallbackMayRunLong-and-instance-st.patch +++ b/patches/ntdll-Vista_Threadpool/0004-ntdll-Implement-TpCallbackMayRunLong-and-instance-st.patch @@ -1,18 +1,18 @@ -From 11233cc79c1790974d7cb401e64f9f8dcc94e1f3 Mon Sep 17 00:00:00 2001 +From 592d1e479946fc84440b05cc03041ccd5ba07a2b Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Wed, 4 Mar 2015 07:25:35 +0100 Subject: ntdll: Implement TpCallbackMayRunLong and instance structure. --- - dlls/ntdll/ntdll.spec | 1 + - dlls/ntdll/threadpool.c | 103 +++++++++++++++++++++++++++++++++++++++++++----- - 2 files changed, 94 insertions(+), 10 deletions(-) + dlls/ntdll/ntdll.spec | 1 + + dlls/ntdll/threadpool.c | 91 +++++++++++++++++++++++++++++++++++++++++++------ + 2 files changed, 82 insertions(+), 10 deletions(-) diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec -index 96edd67..b7f1555 100644 +index 4b5ece5..5a698c4 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec -@@ -971,6 +971,7 @@ +@@ -973,6 +973,7 @@ @ stdcall TpAllocCleanupGroup(ptr) @ stdcall TpAllocPool(ptr ptr) @ stdcall TpAllocWork(ptr ptr ptr ptr) @@ -21,10 +21,10 @@ index 96edd67..b7f1555 100644 @ stdcall TpReleaseCleanupGroup(ptr) @ stdcall TpReleaseCleanupGroupMembers(ptr long ptr) diff --git a/dlls/ntdll/threadpool.c b/dlls/ntdll/threadpool.c -index 47f6f6f..d1733c8 100644 +index 4ae81b0..8634f44 100644 --- a/dlls/ntdll/threadpool.c +++ b/dlls/ntdll/threadpool.c -@@ -172,6 +172,7 @@ struct threadpool_object +@@ -173,6 +173,7 @@ struct threadpool_object PVOID userdata; PTP_CLEANUP_GROUP_CANCEL_CALLBACK group_cancel_callback; PTP_SIMPLE_CALLBACK finalization_callback; @@ -32,7 +32,7 @@ index 47f6f6f..d1733c8 100644 HMODULE race_dll; /* information about the group, locked via .group->cs */ struct list group_entry; -@@ -195,6 +196,14 @@ struct threadpool_object +@@ -196,6 +197,14 @@ struct threadpool_object } u; }; @@ -47,7 +47,7 @@ index 47f6f6f..d1733c8 100644 /* internal threadpool group representation */ struct threadpool_group { -@@ -222,6 +231,11 @@ static inline struct threadpool_group *impl_from_TP_CLEANUP_GROUP( TP_CLEANUP_GR +@@ -223,6 +232,11 @@ static inline struct threadpool_group *impl_from_TP_CLEANUP_GROUP( TP_CLEANUP_GR return (struct threadpool_group *)group; } @@ -59,7 +59,7 @@ index 47f6f6f..d1733c8 100644 static void CALLBACK threadpool_worker_proc( void *param ); static void tp_object_submit( struct threadpool_object *object ); static void tp_object_shutdown( struct threadpool_object *object ); -@@ -1295,6 +1309,7 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa +@@ -1375,6 +1389,7 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa object->userdata = userdata; object->group_cancel_callback = NULL; object->finalization_callback = NULL; @@ -67,73 +67,24 @@ index 47f6f6f..d1733c8 100644 object->race_dll = NULL; memset( &object->group_entry, 0, sizeof(object->group_entry) ); -@@ -1313,9 +1328,14 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa +@@ -1393,9 +1408,14 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa object->group = impl_from_TP_CLEANUP_GROUP( environment->CleanupGroup ); object->group_cancel_callback = environment->CleanupGroupCancelCallback; object->finalization_callback = environment->FinalizationCallback; + object->may_run_long = environment->u.s.LongFunction != 0; object->race_dll = environment->RaceDll; -- WARN("environment not fully implemented yet\n"); +- WARN( "environment not fully implemented yet\n" ); + if (environment->ActivationContext) + FIXME("activation context not supported yet\n"); + + if (environment->u.s.Persistent) -+ FIXME("persistent thread support not supported yet\n"); ++ FIXME("persistent threads not supported yet\n"); } - /* Increase dll refcount */ -@@ -1478,9 +1498,57 @@ static BOOL tp_object_release( struct threadpool_object *object ) - return TRUE; - } - -+/* initializes a threadpool instance structure */ -+static void tp_instance_initialize( struct threadpool_instance *instance, struct threadpool_object *object ) -+{ -+ instance->object = object; -+ instance->threadid = GetCurrentThreadId(); -+ instance->may_run_long = object->may_run_long; -+} -+ -+/* hint for the threadpool that the execution might take long, spawn additional workers */ -+static BOOL tp_instance_may_run_long( struct threadpool_instance *instance ) -+{ -+ struct threadpool_object *object; -+ struct threadpool *pool; -+ NTSTATUS status = STATUS_SUCCESS; -+ -+ if (instance->threadid != GetCurrentThreadId()) -+ { -+ ERR("called from wrong thread, ignoring\n"); -+ return FALSE; -+ } -+ -+ if (instance->may_run_long) -+ return TRUE; -+ -+ object = instance->object; -+ pool = object->pool; -+ RtlEnterCriticalSection( &pool->cs ); -+ -+ if (pool->num_busy_workers >= pool->num_workers && pool->num_workers < pool->max_workers) -+ { -+ HANDLE thread; -+ status = RtlCreateUserThread( GetCurrentProcess(), NULL, FALSE, NULL, 0, 0, -+ threadpool_worker_proc, pool, &thread, NULL ); -+ if (status == STATUS_SUCCESS) -+ { -+ interlocked_inc( &pool->refcount ); -+ pool->num_workers++; -+ NtClose( thread ); -+ } -+ } -+ -+ RtlLeaveCriticalSection( &pool->cs ); -+ instance->may_run_long = TRUE; -+ return !status; -+} -+ - /* threadpool worker function */ + if (object->race_dll) +@@ -1578,6 +1598,8 @@ static BOOL tp_object_release( struct threadpool_object *object ) + */ static void CALLBACK threadpool_worker_proc( void *param ) { + struct threadpool_instance instance; @@ -141,12 +92,15 @@ index 47f6f6f..d1733c8 100644 struct threadpool *pool = param; LARGE_INTEGER timeout; struct list *ptr; -@@ -1503,23 +1571,24 @@ static void CALLBACK threadpool_worker_proc( void *param ) - object->num_running_callbacks++; +@@ -1603,22 +1625,27 @@ static void CALLBACK threadpool_worker_proc( void *param ) pool->num_busy_workers++; RtlLeaveCriticalSection( &pool->cs ); -+ tp_instance_initialize( &instance, object ); ++ /* Initialize threadpool instance struct. */ ++ instance.object = object; ++ instance.threadid = GetCurrentThreadId(); ++ instance.may_run_long = object->may_run_long; ++ switch (object->type) { case TP_OBJECT_TYPE_SIMPLE: @@ -172,8 +126,8 @@ index 47f6f6f..d1733c8 100644 TRACE( "callback %p returned\n", object->u.work.callback ); break; } -@@ -1532,9 +1601,9 @@ static void CALLBACK threadpool_worker_proc( void *param ) - /* Execute finalization callback */ +@@ -1631,9 +1658,9 @@ static void CALLBACK threadpool_worker_proc( void *param ) + /* Execute finalization callback. */ if (object->finalization_callback) { - TRACE( "executing finalization callback %p(NULL, %p)\n", @@ -185,7 +139,7 @@ index 47f6f6f..d1733c8 100644 TRACE( "callback %p returned\n", object->finalization_callback ); } -@@ -1627,6 +1696,20 @@ NTSTATUS WINAPI TpAllocWork( TP_WORK **out, PTP_WORK_CALLBACK callback, PVOID us +@@ -1725,6 +1752,50 @@ NTSTATUS WINAPI TpAllocWork( TP_WORK **out, PTP_WORK_CALLBACK callback, PVOID us } /*********************************************************************** @@ -194,12 +148,42 @@ index 47f6f6f..d1733c8 100644 +NTSTATUS WINAPI TpCallbackMayRunLong( TP_CALLBACK_INSTANCE *instance ) +{ + struct threadpool_instance *this = impl_from_TP_CALLBACK_INSTANCE( instance ); -+ TRACE("%p\n", instance); ++ struct threadpool_object *object = this->object; ++ struct threadpool *pool; ++ NTSTATUS status = STATUS_SUCCESS; + -+ if (!this) -+ return STATUS_ACCESS_VIOLATION; ++ TRACE( "%p\n", instance ); + -+ return tp_instance_may_run_long( this ); ++ if (this->threadid != GetCurrentThreadId()) ++ { ++ ERR("called from wrong thread, ignoring\n"); ++ return STATUS_UNSUCCESSFUL; /* FIXME */ ++ } ++ ++ if (this->may_run_long) ++ return STATUS_SUCCESS; ++ ++ pool = object->pool; ++ RtlEnterCriticalSection( &pool->cs ); ++ ++ /* Start new worker threads if required. */ ++ if (pool->num_busy_workers >= pool->num_workers && ++ pool->num_workers < pool->max_workers) ++ { ++ HANDLE thread; ++ status = RtlCreateUserThread( GetCurrentProcess(), NULL, FALSE, NULL, 0, 0, ++ threadpool_worker_proc, pool, &thread, NULL ); ++ if (status == STATUS_SUCCESS) ++ { ++ interlocked_inc( &pool->refcount ); ++ pool->num_workers++; ++ NtClose( thread ); ++ } ++ } ++ ++ RtlLeaveCriticalSection( &pool->cs ); ++ this->may_run_long = TRUE; ++ return status; +} + +/*********************************************************************** @@ -207,5 +191,5 @@ index 47f6f6f..d1733c8 100644 */ VOID WINAPI TpPostWork( TP_WORK *work ) -- -2.3.3 +2.4.4 diff --git a/patches/ntdll-Vista_Threadpool/0004-ntdll-tests-Add-tests-for-TpAllocCleanupGroup-and-re.patch b/patches/ntdll-Vista_Threadpool/0004-ntdll-tests-Add-tests-for-TpAllocCleanupGroup-and-re.patch deleted file mode 100644 index d5f03f71..00000000 --- a/patches/ntdll-Vista_Threadpool/0004-ntdll-tests-Add-tests-for-TpAllocCleanupGroup-and-re.patch +++ /dev/null @@ -1,102 +0,0 @@ -From f8532f86e968848db4b8e4f87d3556dfcaa753e8 Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Wed, 4 Mar 2015 01:19:41 +0100 -Subject: ntdll/tests: Add tests for TpAllocCleanupGroup and related functions. - ---- - dlls/ntdll/tests/threadpool.c | 48 +++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 48 insertions(+) - -diff --git a/dlls/ntdll/tests/threadpool.c b/dlls/ntdll/tests/threadpool.c -index 6f164e9..effa7fc 100644 ---- a/dlls/ntdll/tests/threadpool.c -+++ b/dlls/ntdll/tests/threadpool.c -@@ -21,7 +21,10 @@ - #include "ntdll_test.h" - - static HMODULE hntdll = 0; -+static NTSTATUS (WINAPI *pTpAllocCleanupGroup)(TP_CLEANUP_GROUP **); - static NTSTATUS (WINAPI *pTpAllocPool)(TP_POOL **,PVOID); -+static VOID (WINAPI *pTpReleaseCleanupGroup)(TP_CLEANUP_GROUP *); -+static VOID (WINAPI *pTpReleaseCleanupGroupMembers)(TP_CLEANUP_GROUP *,BOOL,PVOID); - static VOID (WINAPI *pTpReleasePool)(TP_POOL *); - static NTSTATUS (WINAPI *pTpSimpleTryPost)(PTP_SIMPLE_CALLBACK,PVOID,TP_CALLBACK_ENVIRON *); - -@@ -42,7 +45,10 @@ static BOOL init_threadpool(void) - return FALSE; - } - -+ NTDLL_GET_PROC(TpAllocCleanupGroup); - NTDLL_GET_PROC(TpAllocPool); -+ NTDLL_GET_PROC(TpReleaseCleanupGroup); -+ NTDLL_GET_PROC(TpReleaseCleanupGroupMembers); - NTDLL_GET_PROC(TpReleasePool); - NTDLL_GET_PROC(TpSimpleTryPost); - -@@ -65,13 +71,23 @@ static void CALLBACK simple_cb(TP_CALLBACK_INSTANCE *instance, void *userdata) - ReleaseSemaphore(semaphore, 1, NULL); - } - -+static void CALLBACK simple2_cb(TP_CALLBACK_INSTANCE *instance, void *userdata) -+{ -+ trace("Running simple2 callback\n"); -+ Sleep(100); -+ InterlockedIncrement((LONG *)userdata); -+} -+ - static void test_tp_simple(void) - { - TP_CALLBACK_ENVIRON environment; -+ TP_CLEANUP_GROUP *group; - HANDLE semaphore; - NTSTATUS status; - TP_POOL *pool; -+ LONG userdata; - DWORD result; -+ int i; - - semaphore = CreateSemaphoreA(NULL, 0, 1, NULL); - ok(semaphore != NULL, "CreateSemaphoreA failed %u\n", GetLastError()); -@@ -114,7 +130,39 @@ static void test_tp_simple(void) - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); - } - -+ /* allocate a cleanup group for synchronization */ -+ group = NULL; -+ status = pTpAllocCleanupGroup(&group); -+ ok(!status, "TpAllocCleanupGroup failed with status %x\n", status); -+ ok(group != NULL, "expected pool != NULL\n"); -+ -+ /* use cleanup group to wait for a simple callback */ -+ userdata = 0; -+ memset(&environment, 0, sizeof(environment)); -+ environment.Version = 1; -+ environment.Pool = pool; -+ environment.CleanupGroup = group; -+ status = pTpSimpleTryPost(simple2_cb, &userdata, &environment); -+ ok(!status, "TpSimpleTryPost failed with status %x\n", status); -+ pTpReleaseCleanupGroupMembers(group, FALSE, NULL); -+ ok(userdata == 1, "expected userdata = 1, got %u\n", userdata); -+ -+ /* test cancellation of pending simple callbacks */ -+ userdata = 0; -+ memset(&environment, 0, sizeof(environment)); -+ environment.Version = 1; -+ environment.Pool = pool; -+ environment.CleanupGroup = group; -+ for (i = 0; i < 100; i++) -+ { -+ status = pTpSimpleTryPost(simple2_cb, &userdata, &environment); -+ ok(!status, "TpSimpleTryPost failed with status %x\n", status); -+ } -+ pTpReleaseCleanupGroupMembers(group, TRUE, NULL); -+ ok(userdata < 100, "expected userdata < 100, got %u\n", userdata); -+ - /* cleanup */ -+ pTpReleaseCleanupGroup(group); - pTpReleasePool(pool); - CloseHandle(semaphore); - } --- -2.3.3 - diff --git a/patches/ntdll-Vista_Threadpool/0012-ntdll-Implement-TpDisassociateCallback.patch b/patches/ntdll-Vista_Threadpool/0005-ntdll-Implement-TpDisassociateCallback.patch similarity index 62% rename from patches/ntdll-Vista_Threadpool/0012-ntdll-Implement-TpDisassociateCallback.patch rename to patches/ntdll-Vista_Threadpool/0005-ntdll-Implement-TpDisassociateCallback.patch index 7e0bec92..5a82127e 100644 --- a/patches/ntdll-Vista_Threadpool/0012-ntdll-Implement-TpDisassociateCallback.patch +++ b/patches/ntdll-Vista_Threadpool/0005-ntdll-Implement-TpDisassociateCallback.patch @@ -1,18 +1,18 @@ -From 472f35764b63622fd5887ac16194e8b5089f0fc6 Mon Sep 17 00:00:00 2001 +From e6ab4f5a5525d2d65cafef3b45ccd156105ebe46 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Wed, 4 Mar 2015 07:31:27 +0100 Subject: ntdll: Implement TpDisassociateCallback. --- dlls/ntdll/ntdll.spec | 1 + - dlls/ntdll/threadpool.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++--- - 2 files changed, 50 insertions(+), 3 deletions(-) + dlls/ntdll/threadpool.c | 42 +++++++++++++++++++++++++++++++++++++++--- + 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec -index b7f1555..63426c5 100644 +index 5a698c4..f61728f 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec -@@ -972,6 +972,7 @@ +@@ -974,6 +974,7 @@ @ stdcall TpAllocPool(ptr ptr) @ stdcall TpAllocWork(ptr ptr ptr ptr) @ stdcall TpCallbackMayRunLong(ptr) @@ -21,10 +21,10 @@ index b7f1555..63426c5 100644 @ stdcall TpReleaseCleanupGroup(ptr) @ stdcall TpReleaseCleanupGroupMembers(ptr long ptr) diff --git a/dlls/ntdll/threadpool.c b/dlls/ntdll/threadpool.c -index d1733c8..4861ba6 100644 +index 8634f44..6bd3206 100644 --- a/dlls/ntdll/threadpool.c +++ b/dlls/ntdll/threadpool.c -@@ -201,6 +201,7 @@ struct threadpool_instance +@@ -202,6 +202,7 @@ struct threadpool_instance { struct threadpool_object *object; DWORD threadid; @@ -32,45 +32,15 @@ index d1733c8..4861ba6 100644 BOOL may_run_long; }; -@@ -1503,9 +1504,37 @@ static void tp_instance_initialize( struct threadpool_instance *instance, struct - { - instance->object = object; - instance->threadid = GetCurrentThreadId(); -+ instance->disassociated = FALSE; - instance->may_run_long = object->may_run_long; - } +@@ -1628,6 +1629,7 @@ static void CALLBACK threadpool_worker_proc( void *param ) + /* Initialize threadpool instance struct. */ + instance.object = object; + instance.threadid = GetCurrentThreadId(); ++ instance.disassociated = FALSE; + instance.may_run_long = object->may_run_long; -+/* disassociates the current thread from the threadpool object */ -+static void tp_instance_disassociate_thread( struct threadpool_instance *instance ) -+{ -+ struct threadpool_object *object; -+ struct threadpool *pool; -+ -+ if (instance->threadid != GetCurrentThreadId()) -+ { -+ ERR("called from wrong thread, ignoring\n"); -+ return; -+ } -+ -+ if (instance->disassociated) -+ return; -+ -+ object = instance->object; -+ pool = object->pool; -+ RtlEnterCriticalSection( &pool->cs ); -+ -+ object->num_running_callbacks--; -+ if (!object->num_pending_callbacks && !object->num_running_callbacks) -+ RtlWakeAllConditionVariable( &object->finished_event ); -+ -+ RtlLeaveCriticalSection( &pool->cs ); -+ instance->disassociated = TRUE; -+} -+ - /* hint for the threadpool that the execution might take long, spawn additional workers */ - static BOOL tp_instance_may_run_long( struct threadpool_instance *instance ) - { -@@ -1609,9 +1638,12 @@ static void CALLBACK threadpool_worker_proc( void *param ) + switch (object->type) +@@ -1666,9 +1668,12 @@ static void CALLBACK threadpool_worker_proc( void *param ) RtlEnterCriticalSection( &pool->cs ); pool->num_busy_workers--; @@ -86,7 +56,7 @@ index d1733c8..4861ba6 100644 tp_object_release( object ); } -@@ -1710,6 +1742,20 @@ NTSTATUS WINAPI TpCallbackMayRunLong( TP_CALLBACK_INSTANCE *instance ) +@@ -1796,6 +1801,37 @@ NTSTATUS WINAPI TpCallbackMayRunLong( TP_CALLBACK_INSTANCE *instance ) } /*********************************************************************** @@ -95,12 +65,29 @@ index d1733c8..4861ba6 100644 +VOID WINAPI TpDisassociateCallback( TP_CALLBACK_INSTANCE *instance ) +{ + struct threadpool_instance *this = impl_from_TP_CALLBACK_INSTANCE( instance ); -+ TRACE("%p\n", instance); ++ struct threadpool_object *object = this->object; ++ struct threadpool *pool; + -+ if (this) ++ TRACE( "%p\n", instance ); ++ ++ if (this->threadid != GetCurrentThreadId()) + { -+ tp_instance_disassociate_thread( this ); ++ ERR("called from wrong thread, ignoring\n"); ++ return; + } ++ ++ if (this->disassociated) ++ return; ++ ++ pool = object->pool; ++ RtlEnterCriticalSection( &pool->cs ); ++ ++ object->num_running_callbacks--; ++ if (!object->num_pending_callbacks && !object->num_running_callbacks) ++ RtlWakeAllConditionVariable( &object->finished_event ); ++ ++ RtlLeaveCriticalSection( &pool->cs ); ++ this->disassociated = TRUE; +} + +/*********************************************************************** @@ -108,5 +95,5 @@ index d1733c8..4861ba6 100644 */ VOID WINAPI TpPostWork( TP_WORK *work ) -- -2.3.3 +2.4.4 diff --git a/patches/ntdll-Vista_Threadpool/0005-ntdll-Implement-threadpool-work-item-functions.patch b/patches/ntdll-Vista_Threadpool/0005-ntdll-Implement-threadpool-work-item-functions.patch deleted file mode 100644 index 35f39d65..00000000 --- a/patches/ntdll-Vista_Threadpool/0005-ntdll-Implement-threadpool-work-item-functions.patch +++ /dev/null @@ -1,178 +0,0 @@ -From 20e50fe1839e89ef32df751130d5fc7b20ea095a Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Wed, 4 Mar 2015 01:30:57 +0100 -Subject: ntdll: Implement threadpool work item functions. - ---- - dlls/ntdll/ntdll.spec | 4 +++ - dlls/ntdll/threadpool.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++- - 2 files changed, 97 insertions(+), 1 deletion(-) - -diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec -index 7c01d43..2180ea9 100644 ---- a/dlls/ntdll/ntdll.spec -+++ b/dlls/ntdll/ntdll.spec -@@ -970,12 +970,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 9e0efee..e6bb626 100644 ---- a/dlls/ntdll/threadpool.c -+++ b/dlls/ntdll/threadpool.c -@@ -156,7 +156,8 @@ struct threadpool - - enum threadpool_objtype - { -- TP_OBJECT_TYPE_SIMPLE -+ TP_OBJECT_TYPE_SIMPLE, -+ TP_OBJECT_TYPE_WORK - }; - - /* internal threadpool object representation */ -@@ -184,6 +185,10 @@ struct threadpool_object - { - PTP_SIMPLE_CALLBACK callback; - } simple; -+ struct -+ { -+ PTP_WORK_CALLBACK callback; -+ } work; - } u; - }; - -@@ -202,6 +207,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 || 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; -@@ -1485,6 +1497,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; -@@ -1546,6 +1567,46 @@ 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; -+ -+ TRACE("%p %p %p %p\n", out, callback, userdata, environment); -+ -+ if (!(pool = get_threadpool( environment ))) -+ return STATUS_NO_MEMORY; -+ -+ object = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*object) ); -+ if (!object) -+ return STATUS_NO_MEMORY; -+ -+ 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); -+ -+ if (this) -+ { -+ tp_object_submit( this ); -+ } -+} -+ -+/*********************************************************************** - * TpReleaseCleanupGroup (NTDLL.@) - */ - VOID WINAPI TpReleaseCleanupGroup( TP_CLEANUP_GROUP *group ) -@@ -1640,6 +1701,21 @@ 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); -+ -+ if (this) -+ { -+ tp_object_shutdown( this ); -+ tp_object_release( this ); -+ } -+} -+ -+/*********************************************************************** - * TpSetPoolMaxThreads (NTDLL.@) - */ - VOID WINAPI TpSetPoolMaxThreads( TP_POOL *pool, DWORD maximum ) -@@ -1698,3 +1774,19 @@ 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 %d\n", work, cancel_pending); -+ -+ if (this) -+ { -+ if (cancel_pending) -+ tp_object_cancel( this ); -+ tp_object_wait( this ); -+ } -+} --- -2.3.5 - diff --git a/patches/ntdll-Vista_Threadpool/0013-ntdll-Implement-various-TpCallback-OnCompletion-func.patch b/patches/ntdll-Vista_Threadpool/0006-ntdll-Implement-various-TpCallback-OnCompletion-func.patch similarity index 51% rename from patches/ntdll-Vista_Threadpool/0013-ntdll-Implement-various-TpCallback-OnCompletion-func.patch rename to patches/ntdll-Vista_Threadpool/0006-ntdll-Implement-various-TpCallback-OnCompletion-func.patch index 90e9c525..87715f51 100644 --- a/patches/ntdll-Vista_Threadpool/0013-ntdll-Implement-various-TpCallback-OnCompletion-func.patch +++ b/patches/ntdll-Vista_Threadpool/0006-ntdll-Implement-various-TpCallback-OnCompletion-func.patch @@ -1,18 +1,18 @@ -From 16d0eb264d85a90fa7faf1b429dec1f4efe385a2 Mon Sep 17 00:00:00 2001 +From c38bf17c8f87444feca7e4ce3508e55c581671e9 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Wed, 4 Mar 2015 07:40:02 +0100 Subject: ntdll: Implement various TpCallback*OnCompletion functions. --- - dlls/ntdll/ntdll.spec | 5 ++ - dlls/ntdll/threadpool.c | 153 ++++++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 158 insertions(+) + dlls/ntdll/ntdll.spec | 5 +++ + dlls/ntdll/threadpool.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 115 insertions(+) diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec -index 63426c5..6100a7e 100644 +index f61728f..ee90705 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec -@@ -971,7 +971,12 @@ +@@ -973,7 +973,12 @@ @ stdcall TpAllocCleanupGroup(ptr) @ stdcall TpAllocPool(ptr ptr) @ stdcall TpAllocWork(ptr ptr ptr ptr) @@ -21,15 +21,15 @@ index 63426c5..6100a7e 100644 +@ stdcall TpCallbackReleaseMutexOnCompletion(ptr long) +@ stdcall TpCallbackReleaseSemaphoreOnCompletion(ptr long long) +@ stdcall TpCallbackSetEventOnCompletion(ptr long) -+@ stdcall TpCallbackUnloadDllOnCompletion(ptr long) ++@ stdcall TpCallbackUnloadDllOnCompletion(ptr ptr) @ stdcall TpDisassociateCallback(ptr) @ stdcall TpPostWork(ptr) @ stdcall TpReleaseCleanupGroup(ptr) diff --git a/dlls/ntdll/threadpool.c b/dlls/ntdll/threadpool.c -index 4861ba6..aa2d8e9 100644 +index 6bd3206..9874315 100644 --- a/dlls/ntdll/threadpool.c +++ b/dlls/ntdll/threadpool.c -@@ -203,6 +203,15 @@ struct threadpool_instance +@@ -204,6 +204,15 @@ struct threadpool_instance DWORD threadid; BOOL disassociated; BOOL may_run_long; @@ -45,66 +45,61 @@ index 4861ba6..aa2d8e9 100644 }; /* internal threadpool group representation */ -@@ -1506,8 +1515,50 @@ static void tp_instance_initialize( struct threadpool_instance *instance, struct - instance->threadid = GetCurrentThreadId(); - instance->disassociated = FALSE; - instance->may_run_long = object->may_run_long; -+ instance->cleanup.critical_section = NULL; -+ instance->cleanup.mutex = NULL; -+ instance->cleanup.semaphore = NULL; -+ instance->cleanup.semaphore_count = 0; -+ instance->cleanup.event = NULL; -+ instance->cleanup.library = NULL; - } - -+static NTSTATUS tp_instance_cleanup( struct threadpool_instance *instance ) -+{ +@@ -1604,6 +1613,7 @@ static void CALLBACK threadpool_worker_proc( void *param ) + struct threadpool *pool = param; + LARGE_INTEGER timeout; + struct list *ptr; + NTSTATUS status; -+ -+ if (instance->cleanup.critical_section) -+ { -+ RtlLeaveCriticalSection( instance->cleanup.critical_section ); -+ } -+ if (instance->cleanup.mutex) -+ { -+ status = NtReleaseMutant( instance->cleanup.mutex, NULL ); -+ if (status != STATUS_SUCCESS) -+ return status; -+ } -+ if (instance->cleanup.semaphore) -+ { -+ status = NtReleaseSemaphore( instance->cleanup.semaphore, instance->cleanup.semaphore_count, NULL ); -+ if (status != STATUS_SUCCESS) -+ return status; -+ } -+ if (instance->cleanup.event) -+ { -+ status = NtSetEvent( instance->cleanup.event, NULL ); -+ if (status != STATUS_SUCCESS) -+ return status; -+ } -+ if (instance->cleanup.library) -+ { -+ status = LdrUnloadDll( instance->cleanup.library ); -+ if (status != STATUS_SUCCESS) -+ return status; -+ } -+ -+ return STATUS_SUCCESS; -+ } -+ - /* disassociates the current thread from the threadpool object */ - static void tp_instance_disassociate_thread( struct threadpool_instance *instance ) - { -@@ -1636,6 +1687,7 @@ static void CALLBACK threadpool_worker_proc( void *param ) + + TRACE( "starting worker thread for pool %p\n", pool ); + +@@ -1631,6 +1641,12 @@ static void CALLBACK threadpool_worker_proc( void *param ) + instance.threadid = GetCurrentThreadId(); + instance.disassociated = FALSE; + instance.may_run_long = object->may_run_long; ++ instance.cleanup.critical_section = NULL; ++ instance.cleanup.mutex = NULL; ++ instance.cleanup.semaphore = NULL; ++ instance.cleanup.semaphore_count = 0; ++ instance.cleanup.event = NULL; ++ instance.cleanup.library = NULL; + + switch (object->type) + { +@@ -1666,6 +1682,32 @@ static void CALLBACK threadpool_worker_proc( void *param ) TRACE( "callback %p returned\n", object->finalization_callback ); } -+ tp_instance_cleanup( &instance ); ++ /* Execute cleanup tasks. */ ++ if (instance.cleanup.critical_section) ++ { ++ RtlLeaveCriticalSection( instance.cleanup.critical_section ); ++ } ++ if (instance.cleanup.mutex) ++ { ++ status = NtReleaseMutant( instance.cleanup.mutex, NULL ); ++ if (status != STATUS_SUCCESS) goto skip_cleanup; ++ } ++ if (instance.cleanup.semaphore) ++ { ++ status = NtReleaseSemaphore( instance.cleanup.semaphore, instance.cleanup.semaphore_count, NULL ); ++ if (status != STATUS_SUCCESS) goto skip_cleanup; ++ } ++ if (instance.cleanup.event) ++ { ++ status = NtSetEvent( instance.cleanup.event, NULL ); ++ if (status != STATUS_SUCCESS) goto skip_cleanup; ++ } ++ if (instance.cleanup.library) ++ { ++ LdrUnloadDll( instance.cleanup.library ); ++ } ++ ++ skip_cleanup: RtlEnterCriticalSection( &pool->cs ); pool->num_busy_workers--; if (!instance.disassociated) -@@ -1728,6 +1780,26 @@ NTSTATUS WINAPI TpAllocWork( TP_WORK **out, PTP_WORK_CALLBACK callback, PVOID us +@@ -1757,6 +1799,19 @@ NTSTATUS WINAPI TpAllocWork( TP_WORK **out, PTP_WORK_CALLBACK callback, PVOID us } /*********************************************************************** @@ -113,25 +108,18 @@ index 4861ba6..aa2d8e9 100644 +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) -+ return; ++ TRACE( "%p %p\n", instance, crit ); + -+ if (this->cleanup.critical_section) -+ { -+ FIXME("attempt to set multiple cleanup critical sections\n"); -+ return; -+ } -+ -+ this->cleanup.critical_section = crit; ++ if (!this->cleanup.critical_section) ++ this->cleanup.critical_section = crit; +} + +/*********************************************************************** * TpCallbackMayRunLong (NTDLL.@) */ NTSTATUS WINAPI TpCallbackMayRunLong( TP_CALLBACK_INSTANCE *instance ) -@@ -1742,6 +1814,87 @@ NTSTATUS WINAPI TpCallbackMayRunLong( TP_CALLBACK_INSTANCE *instance ) +@@ -1801,6 +1856,61 @@ NTSTATUS WINAPI TpCallbackMayRunLong( TP_CALLBACK_INSTANCE *instance ) } /*********************************************************************** @@ -140,18 +128,11 @@ index 4861ba6..aa2d8e9 100644 +VOID WINAPI TpCallbackReleaseMutexOnCompletion( TP_CALLBACK_INSTANCE *instance, HANDLE mutex ) +{ + struct threadpool_instance *this = impl_from_TP_CALLBACK_INSTANCE( instance ); -+ TRACE("%p %p\n", instance, mutex); + -+ if (!this) -+ return; ++ TRACE( "%p %p\n", instance, mutex ); + -+ if (this->cleanup.mutex) -+ { -+ FIXME("attempt to set multiple cleanup mutexes\n"); -+ return; -+ } -+ -+ this->cleanup.mutex = mutex; ++ if (!this->cleanup.mutex) ++ this->cleanup.mutex = mutex; +} + +/*********************************************************************** @@ -160,19 +141,14 @@ index 4861ba6..aa2d8e9 100644 +VOID WINAPI TpCallbackReleaseSemaphoreOnCompletion( TP_CALLBACK_INSTANCE *instance, HANDLE semaphore, DWORD count ) +{ + struct threadpool_instance *this = impl_from_TP_CALLBACK_INSTANCE( instance ); -+ TRACE("%p %p %u\n", instance, semaphore, count); + -+ if (!this) -+ return; ++ TRACE( "%p %p %u\n", instance, semaphore, count ); + -+ if (this->cleanup.semaphore) ++ if (!this->cleanup.semaphore) + { -+ FIXME("attempt to set multiple cleanup semaphores\n"); -+ return; ++ this->cleanup.semaphore = semaphore; ++ this->cleanup.semaphore_count = count; + } -+ -+ this->cleanup.semaphore = semaphore; -+ this->cleanup.semaphore_count = count; +} + +/*********************************************************************** @@ -181,18 +157,11 @@ index 4861ba6..aa2d8e9 100644 +VOID WINAPI TpCallbackSetEventOnCompletion( TP_CALLBACK_INSTANCE *instance, HANDLE event ) +{ + struct threadpool_instance *this = impl_from_TP_CALLBACK_INSTANCE( instance ); -+ TRACE("%p %p\n", instance, event); + -+ if (!this) -+ return; ++ TRACE( "%p %p\n", instance, event ); + -+ if (this->cleanup.event) -+ { -+ FIXME("attempt to set multiple cleanup events\n"); -+ return; -+ } -+ -+ this->cleanup.event = event; ++ if (!this->cleanup.event) ++ this->cleanup.event = event; +} + +/*********************************************************************** @@ -201,18 +170,11 @@ index 4861ba6..aa2d8e9 100644 +VOID WINAPI TpCallbackUnloadDllOnCompletion( TP_CALLBACK_INSTANCE *instance, HMODULE module ) +{ + struct threadpool_instance *this = impl_from_TP_CALLBACK_INSTANCE( instance ); -+ TRACE("%p %p\n", instance, module); + -+ if (!this) -+ return; ++ TRACE( "%p %p\n", instance, module ); + -+ if (this->cleanup.library) -+ { -+ FIXME("attempt to set multiple cleanup libraries\n"); -+ return; -+ } -+ -+ this->cleanup.library = module; ++ if (!this->cleanup.library) ++ this->cleanup.library = module; +} + +/*********************************************************************** @@ -220,5 +182,5 @@ index 4861ba6..aa2d8e9 100644 */ VOID WINAPI TpDisassociateCallback( TP_CALLBACK_INSTANCE *instance ) -- -2.3.3 +2.4.4 diff --git a/patches/ntdll-Vista_Threadpool/0006-ntdll-tests-Add-basic-tests-for-threadpool-work-item.patch b/patches/ntdll-Vista_Threadpool/0006-ntdll-tests-Add-basic-tests-for-threadpool-work-item.patch deleted file mode 100644 index 3db0bae2..00000000 --- a/patches/ntdll-Vista_Threadpool/0006-ntdll-tests-Add-basic-tests-for-threadpool-work-item.patch +++ /dev/null @@ -1,108 +0,0 @@ -From a0ad4f0f9186dbce96da918255f2c0cd5f4aae7f Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Wed, 4 Mar 2015 01:38:23 +0100 -Subject: ntdll/tests: Add basic tests for threadpool work items. - ---- - dlls/ntdll/tests/threadpool.c | 59 +++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 59 insertions(+) - -diff --git a/dlls/ntdll/tests/threadpool.c b/dlls/ntdll/tests/threadpool.c -index effa7fc..420979c 100644 ---- a/dlls/ntdll/tests/threadpool.c -+++ b/dlls/ntdll/tests/threadpool.c -@@ -23,10 +23,14 @@ - static HMODULE hntdll = 0; - static NTSTATUS (WINAPI *pTpAllocCleanupGroup)(TP_CLEANUP_GROUP **); - static NTSTATUS (WINAPI *pTpAllocPool)(TP_POOL **,PVOID); -+static NTSTATUS (WINAPI *pTpAllocWork)(TP_WORK **,PTP_WORK_CALLBACK,PVOID,TP_CALLBACK_ENVIRON *); -+static VOID (WINAPI *pTpPostWork)(TP_WORK *); - static VOID (WINAPI *pTpReleaseCleanupGroup)(TP_CLEANUP_GROUP *); - static VOID (WINAPI *pTpReleaseCleanupGroupMembers)(TP_CLEANUP_GROUP *,BOOL,PVOID); - static VOID (WINAPI *pTpReleasePool)(TP_POOL *); -+static VOID (WINAPI *pTpReleaseWork)(TP_WORK *); - static NTSTATUS (WINAPI *pTpSimpleTryPost)(PTP_SIMPLE_CALLBACK,PVOID,TP_CALLBACK_ENVIRON *); -+static VOID (WINAPI *pTpWaitForWork)(TP_WORK *,BOOL); - - #define NTDLL_GET_PROC(func) \ - do \ -@@ -47,10 +51,14 @@ static BOOL init_threadpool(void) - - NTDLL_GET_PROC(TpAllocCleanupGroup); - NTDLL_GET_PROC(TpAllocPool); -+ NTDLL_GET_PROC(TpAllocWork); -+ NTDLL_GET_PROC(TpPostWork); - NTDLL_GET_PROC(TpReleaseCleanupGroup); - NTDLL_GET_PROC(TpReleaseCleanupGroupMembers); - NTDLL_GET_PROC(TpReleasePool); -+ NTDLL_GET_PROC(TpReleaseWork); - NTDLL_GET_PROC(TpSimpleTryPost); -+ NTDLL_GET_PROC(TpWaitForWork); - - if (!pTpAllocPool) - { -@@ -167,10 +175,61 @@ static void test_tp_simple(void) - CloseHandle(semaphore); - } - -+static void CALLBACK work_cb(TP_CALLBACK_INSTANCE *instance, void *userdata, TP_WORK *work) -+{ -+ trace("Running work callback\n"); -+ Sleep(10); -+ InterlockedIncrement((LONG *)userdata); -+} -+ -+static void test_tp_work(void) -+{ -+ TP_CALLBACK_ENVIRON environment; -+ TP_WORK *work; -+ TP_POOL *pool; -+ NTSTATUS status; -+ LONG userdata; -+ int i; -+ -+ /* allocate new threadpool */ -+ pool = NULL; -+ status = pTpAllocPool(&pool, NULL); -+ ok(!status, "TpAllocPool failed with status %x\n", status); -+ ok(pool != NULL, "expected pool != NULL\n"); -+ -+ /* allocate new work item */ -+ work = NULL; -+ memset(&environment, 0, sizeof(environment)); -+ environment.Version = 1; -+ environment.Pool = pool; -+ status = pTpAllocWork(&work, work_cb, &userdata, &environment); -+ ok(!status, "TpAllocWork failed with status %x\n", status); -+ ok(work != NULL, "expected work != NULL\n"); -+ -+ /* post 10 identical work items at once */ -+ userdata = 0; -+ for (i = 0; i < 10; i++) -+ pTpPostWork(work); -+ pTpWaitForWork(work, FALSE); -+ ok(userdata == 10, "expected userdata = 10, got %u\n", userdata); -+ -+ /* add more tasks and cancel them immediately */ -+ userdata = 0; -+ for (i = 0; i < 10; i++) -+ pTpPostWork(work); -+ pTpWaitForWork(work, TRUE); -+ ok(userdata < 10, "expected userdata < 10, got %u\n", userdata); -+ -+ /* cleanup */ -+ pTpReleaseWork(work); -+ pTpReleasePool(pool); -+} -+ - START_TEST(threadpool) - { - if (!init_threadpool()) - return; - - test_tp_simple(); -+ test_tp_work(); - } --- -2.3.3 - diff --git a/patches/ntdll-Vista_Threadpool/0014-ntdll-Add-remaining-threadpool-functions-to-specfile.patch b/patches/ntdll-Vista_Threadpool/0007-ntdll-Add-remaining-threadpool-functions-to-specfile.patch similarity index 94% rename from patches/ntdll-Vista_Threadpool/0014-ntdll-Add-remaining-threadpool-functions-to-specfile.patch rename to patches/ntdll-Vista_Threadpool/0007-ntdll-Add-remaining-threadpool-functions-to-specfile.patch index f4110e6d..e5736d51 100644 --- a/patches/ntdll-Vista_Threadpool/0014-ntdll-Add-remaining-threadpool-functions-to-specfile.patch +++ b/patches/ntdll-Vista_Threadpool/0007-ntdll-Add-remaining-threadpool-functions-to-specfile.patch @@ -1,4 +1,4 @@ -From 01b8c400e280f1c033878cdc16f902a4c47c82df Mon Sep 17 00:00:00 2001 +From 75e6178d889b0883a03119d372858751d130b751 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Wed, 4 Mar 2015 08:01:00 +0100 Subject: ntdll: Add remaining threadpool functions to specfile. @@ -8,10 +8,10 @@ Subject: ntdll: Add remaining threadpool functions to specfile. 1 file changed, 43 insertions(+) diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec -index c42356c..681c75e 100644 +index ee90705..d75efdc 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec -@@ -968,24 +968,67 @@ +@@ -970,24 +970,67 @@ @ stdcall RtlxOemStringToUnicodeSize(ptr) RtlOemStringToUnicodeSize @ stdcall RtlxUnicodeStringToAnsiSize(ptr) RtlUnicodeStringToAnsiSize @ stdcall RtlxUnicodeStringToOemSize(ptr) RtlUnicodeStringToOemSize @@ -35,7 +35,7 @@ index c42356c..681c75e 100644 +# @ stub TpCallbackSendAlpcMessageOnCompletion +# @ stub TpCallbackSendPendingAlpcMessage @ stdcall TpCallbackSetEventOnCompletion(ptr long) - @ stdcall TpCallbackUnloadDllOnCompletion(ptr long) + @ stdcall TpCallbackUnloadDllOnCompletion(ptr ptr) +# @ stub TpCancelAsyncIoOperation +# @ stub TpCaptureCaller +# @ stub TpCheckTerminateWorker @@ -80,5 +80,5 @@ index c42356c..681c75e 100644 @ stdcall -ret64 VerSetConditionMask(int64 long long) @ stdcall WinSqmIsOptedIn() -- -2.3.5 +2.4.4 diff --git a/patches/ntdll-Vista_Threadpool/0007-ntdll-tests-Add-threadpool-scheduler-tests-for-work-.patch b/patches/ntdll-Vista_Threadpool/0007-ntdll-tests-Add-threadpool-scheduler-tests-for-work-.patch deleted file mode 100644 index e9b901a6..00000000 --- a/patches/ntdll-Vista_Threadpool/0007-ntdll-tests-Add-threadpool-scheduler-tests-for-work-.patch +++ /dev/null @@ -1,132 +0,0 @@ -From 792ceb3a01f63e523811d42d7a28f6e31a70e2f7 Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Wed, 4 Mar 2015 01:45:11 +0100 -Subject: ntdll/tests: Add threadpool scheduler tests for work items. - ---- - dlls/ntdll/tests/threadpool.c | 83 +++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 83 insertions(+) - -diff --git a/dlls/ntdll/tests/threadpool.c b/dlls/ntdll/tests/threadpool.c -index 420979c..1cfd67b 100644 ---- a/dlls/ntdll/tests/threadpool.c -+++ b/dlls/ntdll/tests/threadpool.c -@@ -29,6 +29,7 @@ static VOID (WINAPI *pTpReleaseCleanupGroup)(TP_CLEANUP_GROUP *); - static VOID (WINAPI *pTpReleaseCleanupGroupMembers)(TP_CLEANUP_GROUP *,BOOL,PVOID); - static VOID (WINAPI *pTpReleasePool)(TP_POOL *); - static VOID (WINAPI *pTpReleaseWork)(TP_WORK *); -+static VOID (WINAPI *pTpSetPoolMaxThreads)(TP_POOL *,DWORD); - static NTSTATUS (WINAPI *pTpSimpleTryPost)(PTP_SIMPLE_CALLBACK,PVOID,TP_CALLBACK_ENVIRON *); - static VOID (WINAPI *pTpWaitForWork)(TP_WORK *,BOOL); - -@@ -57,6 +58,7 @@ static BOOL init_threadpool(void) - NTDLL_GET_PROC(TpReleaseCleanupGroupMembers); - NTDLL_GET_PROC(TpReleasePool); - NTDLL_GET_PROC(TpReleaseWork); -+ NTDLL_GET_PROC(TpSetPoolMaxThreads); - NTDLL_GET_PROC(TpSimpleTryPost); - NTDLL_GET_PROC(TpWaitForWork); - -@@ -182,6 +184,13 @@ static void CALLBACK work_cb(TP_CALLBACK_INSTANCE *instance, void *userdata, TP_ - InterlockedIncrement((LONG *)userdata); - } - -+static void CALLBACK work2_cb(TP_CALLBACK_INSTANCE *instance, void *userdata, TP_WORK *work) -+{ -+ trace("Running work2 callback\n"); -+ Sleep(10); -+ InterlockedExchangeAdd((LONG *)userdata, 0x10000); -+} -+ - static void test_tp_work(void) - { - TP_CALLBACK_ENVIRON environment; -@@ -225,6 +234,79 @@ static void test_tp_work(void) - pTpReleasePool(pool); - } - -+static void test_tp_work_scheduler(void) -+{ -+ TP_CALLBACK_ENVIRON environment; -+ TP_CLEANUP_GROUP *group; -+ TP_WORK *work, *work2; -+ TP_POOL *pool; -+ NTSTATUS status; -+ LONG userdata; -+ int i; -+ -+ /* allocate new threadpool */ -+ pool = NULL; -+ status = pTpAllocPool(&pool, NULL); -+ ok(!status, "TpAllocPool failed with status %x\n", status); -+ ok(pool != NULL, "expected pool != NULL\n"); -+ -+ /* we limit the pool to a single thread */ -+ pTpSetPoolMaxThreads(pool, 1); -+ -+ /* create a cleanup group */ -+ group = NULL; -+ status = pTpAllocCleanupGroup(&group); -+ ok(!status, "TpAllocCleanupGroup failed with status %x\n", status); -+ ok(group != NULL, "expected pool != NULL\n"); -+ -+ /* the first work item has no cleanup group associated */ -+ work = NULL; -+ memset(&environment, 0, sizeof(environment)); -+ environment.Version = 1; -+ environment.Pool = pool; -+ status = pTpAllocWork(&work, work_cb, &userdata, &environment); -+ ok(!status, "TpAllocWork failed with status %x\n", status); -+ ok(work != NULL, "expected work != NULL\n"); -+ -+ /* allocate a second work item with a cleanup group */ -+ work2 = NULL; -+ memset(&environment, 0, sizeof(environment)); -+ environment.Version = 1; -+ environment.Pool = pool; -+ environment.CleanupGroup = group; -+ status = pTpAllocWork(&work2, work2_cb, &userdata, &environment); -+ ok(!status, "TpAllocWork failed with status %x\n", status); -+ ok(work2 != NULL, "expected work2 != NULL\n"); -+ -+ /* the 'work' callbacks are not blocking execution of 'work2' callbacks */ -+ userdata = 0; -+ for (i = 0; i < 10; i++) -+ pTpPostWork(work); -+ for (i = 0; i < 10; i++) -+ pTpPostWork(work2); -+ Sleep(30); -+ pTpWaitForWork(work, TRUE); -+ pTpWaitForWork(work2, TRUE); -+ ok(userdata & 0xffff, "expected userdata & 0xffff != 0, got %u\n", userdata & 0xffff); -+ ok(userdata >> 16, "expected userdata >> 16 != 0, got %u\n", userdata >> 16); -+ -+ /* test ReleaseCleanupGroupMembers on a work item */ -+ userdata = 0; -+ for (i = 0; i < 100; i++) -+ pTpPostWork(work); -+ for (i = 0; i < 10; i++) -+ pTpPostWork(work2); -+ pTpReleaseCleanupGroupMembers(group, FALSE, NULL); -+ pTpWaitForWork(work, TRUE); -+ ok((userdata & 0xffff) < 100, "expected userdata & 0xffff < 100, got %u\n", userdata & 0xffff); -+ ok((userdata >> 16) == 10, "expected userdata >> 16 == 10, got %u\n", userdata >> 16); -+ -+ /* cleanup */ -+ pTpReleaseWork(work); -+ pTpReleaseCleanupGroup(group); -+ pTpReleasePool(pool); -+} -+ - START_TEST(threadpool) - { - if (!init_threadpool()) -@@ -232,4 +314,5 @@ START_TEST(threadpool) - - test_tp_simple(); - test_tp_work(); -+ test_tp_work_scheduler(); - } --- -2.3.3 - diff --git a/patches/ntdll-Vista_Threadpool/0015-ntdll-Implement-threadpool-timer-functions.-rev-2.patch b/patches/ntdll-Vista_Threadpool/0008-ntdll-Implement-threadpool-timer-functions.-rev-2.patch similarity index 89% rename from patches/ntdll-Vista_Threadpool/0015-ntdll-Implement-threadpool-timer-functions.-rev-2.patch rename to patches/ntdll-Vista_Threadpool/0008-ntdll-Implement-threadpool-timer-functions.-rev-2.patch index 22b4556e..4ba212ab 100644 --- a/patches/ntdll-Vista_Threadpool/0015-ntdll-Implement-threadpool-timer-functions.-rev-2.patch +++ b/patches/ntdll-Vista_Threadpool/0008-ntdll-Implement-threadpool-timer-functions.-rev-2.patch @@ -1,4 +1,4 @@ -From 90370a65b5f492ebe3fafb5e35548eb4b6681dac Mon Sep 17 00:00:00 2001 +From 04e6df6c221a7f6fc57cfb431d889e62fe64fc47 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Wed, 4 Mar 2015 08:19:47 +0100 Subject: ntdll: Implement threadpool timer functions. (rev 2) @@ -9,10 +9,10 @@ Subject: ntdll: Implement threadpool timer functions. (rev 2) 2 files changed, 380 insertions(+), 6 deletions(-) diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec -index 19e63a5..7aa8bda 100644 +index d75efdc..0f4374e 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec -@@ -974,7 +974,7 @@ +@@ -976,7 +976,7 @@ # @ stub TpAllocIoCompletion # @ stub TpAllocJobNotification @ stdcall TpAllocPool(ptr ptr) @@ -21,7 +21,7 @@ index 19e63a5..7aa8bda 100644 # @ stub TpAllocWait @ stdcall TpAllocWork(ptr ptr ptr ptr) # @ stub TpAlpcRegisterCompletionList -@@ -996,7 +996,7 @@ +@@ -998,7 +998,7 @@ # @ stub TpDbgSetLogRoutine # @ stub TpDisablePoolCallbackChecks @ stdcall TpDisassociateCallback(ptr) @@ -30,7 +30,7 @@ index 19e63a5..7aa8bda 100644 @ stdcall TpPostWork(ptr) # @ stub TpQueryPoolStackInformation # @ stub TpReleaseAlpcCompletion -@@ -1005,7 +1005,7 @@ +@@ -1007,7 +1007,7 @@ # @ stub TpReleaseIoCompletion # @ stub TpReleaseJobNotification @ stdcall TpReleasePool(ptr) @@ -39,7 +39,7 @@ index 19e63a5..7aa8bda 100644 # @ stub TpReleaseWait @ stdcall TpReleaseWork(ptr) # @ stub TpSetDefaultPoolMaxThreads -@@ -1016,7 +1016,7 @@ +@@ -1018,7 +1018,7 @@ # @ stub TpSetPoolStackInformation # @ stub TpSetPoolThreadBasePriority # @ stub TpSetPoolWorkerThreadIdleTimeout @@ -48,7 +48,7 @@ index 19e63a5..7aa8bda 100644 # @ stub TpSetTimerEx # @ stub TpSetWait # @ stub TpSetWaitEx -@@ -1027,7 +1027,7 @@ +@@ -1029,7 +1029,7 @@ # @ stub TpWaitForAlpcCompletion # @ stub TpWaitForIoCompletion # @ stub TpWaitForJobNotification @@ -58,10 +58,10 @@ index 19e63a5..7aa8bda 100644 @ stdcall TpWaitForWork(ptr long) @ stdcall -ret64 VerSetConditionMask(int64 long long) diff --git a/dlls/ntdll/threadpool.c b/dlls/ntdll/threadpool.c -index 351c1bd..493e0af 100644 +index 9874315..f4c9cba 100644 --- a/dlls/ntdll/threadpool.c +++ b/dlls/ntdll/threadpool.c -@@ -157,7 +157,8 @@ struct threadpool +@@ -158,7 +158,8 @@ struct threadpool enum threadpool_objtype { TP_OBJECT_TYPE_SIMPLE, @@ -71,7 +71,7 @@ index 351c1bd..493e0af 100644 }; /* internal threadpool object representation */ -@@ -193,6 +194,18 @@ struct threadpool_object +@@ -194,6 +195,18 @@ struct threadpool_object { PTP_WORK_CALLBACK callback; } work; @@ -90,7 +90,7 @@ index 351c1bd..493e0af 100644 } u; }; -@@ -224,6 +237,33 @@ struct threadpool_group +@@ -225,6 +238,33 @@ struct threadpool_group struct list members; }; @@ -124,21 +124,21 @@ index 351c1bd..493e0af 100644 static inline struct threadpool *impl_from_TP_POOL( TP_POOL *pool ) { return (struct threadpool *)pool; -@@ -236,6 +276,13 @@ static inline struct threadpool_object *impl_from_TP_WORK( TP_WORK *work ) +@@ -237,6 +277,13 @@ static inline struct threadpool_object *impl_from_TP_WORK( TP_WORK *work ) return object; } +static inline struct threadpool_object *impl_from_TP_TIMER( TP_TIMER *timer ) +{ + struct threadpool_object *object = (struct threadpool_object *)timer; -+ assert( !object || object->type == TP_OBJECT_TYPE_TIMER ); ++ assert( object->type == TP_OBJECT_TYPE_TIMER ); + return object; +} + static inline struct threadpool_group *impl_from_TP_CLEANUP_GROUP( TP_CLEANUP_GROUP *group ) { return (struct threadpool_group *)group; -@@ -247,6 +294,7 @@ static inline struct threadpool_instance *impl_from_TP_CALLBACK_INSTANCE( TP_CAL +@@ -248,6 +295,7 @@ static inline struct threadpool_instance *impl_from_TP_CALLBACK_INSTANCE( TP_CAL } static void CALLBACK threadpool_worker_proc( void *param ); @@ -146,7 +146,7 @@ index 351c1bd..493e0af 100644 static void tp_object_submit( struct threadpool_object *object ); static void tp_object_shutdown( struct threadpool_object *object ); static BOOL tp_object_release( struct threadpool_object *object ); -@@ -1170,6 +1218,230 @@ NTSTATUS WINAPI RtlDeleteTimer(HANDLE TimerQueue, HANDLE Timer, +@@ -1171,6 +1219,230 @@ NTSTATUS WINAPI RtlDeleteTimer(HANDLE TimerQueue, HANDLE Timer, return status; } @@ -374,11 +374,11 @@ index 351c1bd..493e0af 100644 + RtlLeaveCriticalSection( &timerqueue.cs ); +} + - /* allocate a new threadpool (with at least one worker thread) */ - static NTSTATUS tp_threadpool_alloc( struct threadpool **out ) - { -@@ -1473,6 +1745,9 @@ static void tp_object_wait( struct threadpool_object *object ) - /* mark an object as 'shutdown', submitting is no longer possible */ + /*********************************************************************** + * tp_threadpool_alloc (internal) + * +@@ -1559,6 +1831,9 @@ static void tp_object_wait( struct threadpool_object *object ) + */ static void tp_object_shutdown( struct threadpool_object *object ) { + if (object->type == TP_OBJECT_TYPE_TIMER) @@ -387,7 +387,7 @@ index 351c1bd..493e0af 100644 object->shutdown = TRUE; } -@@ -1680,6 +1955,15 @@ static void CALLBACK threadpool_worker_proc( void *param ) +@@ -1668,6 +1943,15 @@ static void CALLBACK threadpool_worker_proc( void *param ) break; } @@ -403,7 +403,7 @@ index 351c1bd..493e0af 100644 default: assert(0); break; -@@ -1754,6 +2038,41 @@ NTSTATUS WINAPI TpAllocPool( TP_POOL **out, PVOID reserved ) +@@ -1768,6 +2052,46 @@ NTSTATUS WINAPI TpAllocPool( TP_POOL **out, PVOID reserved ) } /*********************************************************************** @@ -416,21 +416,26 @@ index 351c1bd..493e0af 100644 + struct threadpool *pool; + NTSTATUS status; + -+ TRACE("%p %p %p %p\n", out, callback, userdata, environment); -+ -+ if (!(pool = get_threadpool( environment ))) -+ return STATUS_NO_MEMORY; ++ 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_TIMER; + object->u.timer.callback = callback; + + status = tp_timerqueue_acquire( object ); + if (status) + { ++ tp_threadpool_unlock( pool ); + RtlFreeHeap( GetProcessHeap(), 0, object ); + return status; + } @@ -445,7 +450,7 @@ index 351c1bd..493e0af 100644 * TpAllocWork (NTDLL.@) */ NTSTATUS WINAPI TpAllocWork( TP_WORK **out, PTP_WORK_CALLBACK callback, PVOID userdata, -@@ -1909,6 +2228,17 @@ VOID WINAPI TpDisassociateCallback( TP_CALLBACK_INSTANCE *instance ) +@@ -1942,6 +2266,17 @@ VOID WINAPI TpDisassociateCallback( TP_CALLBACK_INSTANCE *instance ) } /*********************************************************************** @@ -454,16 +459,16 @@ index 351c1bd..493e0af 100644 +BOOL WINAPI TpIsTimerSet( TP_TIMER *timer ) +{ + struct threadpool_object *this = impl_from_TP_TIMER( timer ); -+ TRACE("%p\n", timer); ++ TRACE( "%p\n", timer ); + -+ return this ? this->u.timer.timer_set : FALSE; ++ return this->u.timer.timer_set; +} + +/*********************************************************************** * TpPostWork (NTDLL.@) */ VOID WINAPI TpPostWork( TP_WORK *work ) -@@ -2017,6 +2347,21 @@ VOID WINAPI TpReleasePool( TP_POOL *pool ) +@@ -2041,6 +2376,19 @@ VOID WINAPI TpReleasePool( TP_POOL *pool ) } /*********************************************************************** @@ -472,20 +477,18 @@ index 351c1bd..493e0af 100644 +VOID WINAPI TpReleaseTimer( TP_TIMER *timer ) +{ + struct threadpool_object *this = impl_from_TP_TIMER( timer ); -+ TRACE("%p\n", timer); + -+ if (this) -+ { -+ tp_object_shutdown( this ); -+ tp_object_release( this ); -+ } ++ TRACE( "%p\n", timer ); ++ ++ tp_object_shutdown( this ); ++ tp_object_release( this ); +} + +/*********************************************************************** * TpReleaseWork (NTDLL.@) */ VOID WINAPI TpReleaseWork( TP_WORK *work ) -@@ -2065,6 +2410,20 @@ BOOL WINAPI TpSetPoolMinThreads( TP_POOL *pool, DWORD minimum ) +@@ -2104,6 +2452,18 @@ BOOL WINAPI TpSetPoolMinThreads( TP_POOL *pool, DWORD minimum ) } /*********************************************************************** @@ -494,19 +497,17 @@ index 351c1bd..493e0af 100644 +VOID WINAPI TpSetTimer( TP_TIMER *timer, LARGE_INTEGER *timeout, LONG period, LONG window_length ) +{ + struct threadpool_object *this = impl_from_TP_TIMER( timer ); -+ TRACE("%p %p %u %u\n", timer, timeout, period, window_length); + -+ if (this) -+ { -+ tp_timerqueue_update_timer( this, timeout, period, window_length ); -+ } ++ TRACE( "%p %p %u %u\n", timer, timeout, period, window_length ); ++ ++ tp_timerqueue_update_timer( this, timeout, period, window_length ); +} + +/*********************************************************************** * TpSimpleTryPost (NTDLL.@) */ NTSTATUS WINAPI TpSimpleTryPost( PTP_SIMPLE_CALLBACK callback, PVOID userdata, -@@ -2090,6 +2449,21 @@ NTSTATUS WINAPI TpSimpleTryPost( PTP_SIMPLE_CALLBACK callback, PVOID userdata, +@@ -2134,6 +2494,20 @@ NTSTATUS WINAPI TpSimpleTryPost( PTP_SIMPLE_CALLBACK callback, PVOID userdata, } /*********************************************************************** @@ -515,13 +516,12 @@ index 351c1bd..493e0af 100644 +VOID WINAPI TpWaitForTimer( TP_TIMER *timer, BOOL cancel_pending ) +{ + struct threadpool_object *this = impl_from_TP_TIMER( timer ); -+ TRACE("%p %d\n", timer, cancel_pending); -+ if (this) -+ { -+ if (cancel_pending) -+ tp_object_cancel( this, FALSE, NULL ); -+ tp_object_wait( this ); -+ } ++ ++ TRACE( "%p %d\n", timer, cancel_pending ); ++ ++ if (cancel_pending) ++ tp_object_cancel( this, FALSE, NULL ); ++ tp_object_wait( this ); +} + +/*********************************************************************** @@ -529,5 +529,5 @@ index 351c1bd..493e0af 100644 */ VOID WINAPI TpWaitForWork( TP_WORK *work, BOOL cancel_pending ) -- -2.3.3 +2.4.4 diff --git a/patches/ntdll-Vista_Threadpool/0016-ntdll-tests-Add-tests-for-Tp-threadpool-functions.patch b/patches/ntdll-Vista_Threadpool/0009-ntdll-tests-Add-tests-for-Tp-threadpool-functions.patch similarity index 99% rename from patches/ntdll-Vista_Threadpool/0016-ntdll-tests-Add-tests-for-Tp-threadpool-functions.patch rename to patches/ntdll-Vista_Threadpool/0009-ntdll-tests-Add-tests-for-Tp-threadpool-functions.patch index 63dfa49c..293bc9df 100644 --- a/patches/ntdll-Vista_Threadpool/0016-ntdll-tests-Add-tests-for-Tp-threadpool-functions.patch +++ b/patches/ntdll-Vista_Threadpool/0009-ntdll-tests-Add-tests-for-Tp-threadpool-functions.patch @@ -1,4 +1,4 @@ -From 4a3ad1401f815720b35b0ab48e6ab1cc08835f5e Mon Sep 17 00:00:00 2001 +From 8d1fba2b1f7b014130cfb64447cba2c2d257864a Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Wed, 4 Mar 2015 13:17:04 +0100 Subject: ntdll/tests: Add tests for Tp* threadpool functions. @@ -8,7 +8,7 @@ Subject: ntdll/tests: Add tests for Tp* threadpool functions. 1 file changed, 470 insertions(+) diff --git a/dlls/ntdll/tests/threadpool.c b/dlls/ntdll/tests/threadpool.c -index 1cfd67b..b44b0f5 100644 +index b261cd1..76db2d0 100644 --- a/dlls/ntdll/tests/threadpool.c +++ b/dlls/ntdll/tests/threadpool.c @@ -22,15 +22,37 @@ @@ -526,5 +526,5 @@ index 1cfd67b..b44b0f5 100644 + Sleep(100); } -- -2.3.3 +2.4.4 diff --git a/patches/ntdll-Vista_Threadpool/0017-kernel32-Forward-various-threadpool-functions-to-ntd.patch b/patches/ntdll-Vista_Threadpool/0010-kernel32-Forward-various-threadpool-functions-to-ntd.patch similarity index 97% rename from patches/ntdll-Vista_Threadpool/0017-kernel32-Forward-various-threadpool-functions-to-ntd.patch rename to patches/ntdll-Vista_Threadpool/0010-kernel32-Forward-various-threadpool-functions-to-ntd.patch index f2644bd8..5da4225f 100644 --- a/patches/ntdll-Vista_Threadpool/0017-kernel32-Forward-various-threadpool-functions-to-ntd.patch +++ b/patches/ntdll-Vista_Threadpool/0010-kernel32-Forward-various-threadpool-functions-to-ntd.patch @@ -1,4 +1,4 @@ -From 6a7aaa0145d32fde06229bae7f8cb879ea2ac182 Mon Sep 17 00:00:00 2001 +From e6dda25c2975565acf141011fba0694b27c8c8a0 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Sun, 1 Feb 2015 19:41:13 +0100 Subject: kernel32: Forward various threadpool functions to ntdll. @@ -11,7 +11,7 @@ Subject: kernel32: Forward various threadpool functions to ntdll. 4 files changed, 155 insertions(+), 27 deletions(-) diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec -index 1179af2..f65f894 100644 +index 3c40975..337b339 100644 --- a/dlls/kernel32/kernel32.spec +++ b/dlls/kernel32/kernel32.spec @@ -204,7 +204,7 @@ @@ -84,7 +84,7 @@ index 1179af2..f65f894 100644 @ stdcall FreeResource(long) @ stdcall -i386 -private FreeSLCallback(long) krnl386.exe16.FreeSLCallback @ stub FreeUserPhysicalPages -@@ -980,7 +980,7 @@ +@@ -981,7 +981,7 @@ @ stub -i386 IsSLCallback @ stdcall IsSystemResumeAutomatic() @ stdcall IsThreadAFiber() @@ -93,7 +93,7 @@ index 1179af2..f65f894 100644 # @ stub IsTimeZoneRedirectionEnabled # @ stub IsValidCalDateTime @ stdcall IsValidCodePage(long) -@@ -1034,7 +1034,7 @@ +@@ -1035,7 +1035,7 @@ @ stdcall LZSeek(long long long) @ stdcall LZStart() @ stdcall LeaveCriticalSection(ptr) ntdll.RtlLeaveCriticalSection @@ -102,7 +102,7 @@ index 1179af2..f65f894 100644 # @ stub LoadAppInitDlls @ stdcall LoadLibraryA(str) @ stdcall LoadLibraryExA( str long long) -@@ -1251,9 +1251,9 @@ +@@ -1252,9 +1252,9 @@ @ stdcall ReinitializeCriticalSection(ptr) @ stdcall ReleaseActCtx(ptr) @ stdcall ReleaseMutex(long) @@ -114,7 +114,7 @@ index 1179af2..f65f894 100644 @ stdcall ReleaseSRWLockExclusive(ptr) ntdll.RtlReleaseSRWLockExclusive @ stdcall ReleaseSRWLockShared(ptr) ntdll.RtlReleaseSRWLockShared @ stdcall RemoveDirectoryA(str) -@@ -1384,7 +1384,7 @@ +@@ -1385,7 +1385,7 @@ @ stdcall SetEnvironmentVariableW(wstr wstr) @ stdcall SetErrorMode(long) @ stdcall SetEvent(long) @@ -123,7 +123,7 @@ index 1179af2..f65f894 100644 @ stdcall SetFileApisToANSI() @ stdcall SetFileApisToOEM() @ stdcall SetFileAttributesA(str long) -@@ -1453,9 +1453,9 @@ +@@ -1454,9 +1454,9 @@ # @ stub SetThreadToken @ stdcall SetThreadUILanguage(long) # @ stub SetThreadpoolStackInformation @@ -136,7 +136,7 @@ index 1179af2..f65f894 100644 # @ stub SetThreadpoolWait @ stdcall SetTimeZoneInformation(ptr) @ stub SetTimerQueueTimer -@@ -1481,7 +1481,7 @@ +@@ -1482,7 +1482,7 @@ # @ stub SortCloseHandle # @ stub SortGetHandle # @ stub StartThreadpoolIo @@ -145,7 +145,7 @@ index 1179af2..f65f894 100644 @ stdcall SuspendThread(long) @ stdcall SwitchToFiber(ptr) @ stdcall SwitchToThread() -@@ -1508,7 +1508,7 @@ +@@ -1509,7 +1509,7 @@ @ stdcall TryAcquireSRWLockExclusive(ptr) ntdll.RtlTryAcquireSRWLockExclusive @ stdcall TryAcquireSRWLockShared(ptr) ntdll.RtlTryAcquireSRWLockShared @ stdcall TryEnterCriticalSection(ptr) ntdll.RtlTryEnterCriticalSection @@ -154,7 +154,7 @@ index 1179af2..f65f894 100644 @ stdcall TzSpecificLocalTimeToSystemTime(ptr ptr ptr) # @ stub TzSpecificLocalTimeToSystemTimeEx # @ stub -arch=x86_64 uaw_lstrcmpW -@@ -1570,9 +1570,9 @@ +@@ -1571,9 +1571,9 @@ @ stdcall WaitForSingleObject(long long) @ stdcall WaitForSingleObjectEx(long long long) # @ stub WaitForThreadpoolIoCallbacks @@ -300,10 +300,10 @@ index 3dabf94..945fe0b 100644 + TpSetTimer( timer, due_time ? &timeout : NULL, period, window_length ); +} diff --git a/include/winternl.h b/include/winternl.h -index f88001f..4f16d24 100644 +index a84c6d4..e1707fd 100644 --- a/include/winternl.h +++ b/include/winternl.h -@@ -2596,6 +2596,33 @@ NTSYSAPI LONGLONG WINAPI RtlLargeIntegerSubtract(LONGLONG,LONGLONG); +@@ -2616,6 +2616,33 @@ NTSYSAPI LONGLONG WINAPI RtlLargeIntegerSubtract(LONGLONG,LONGLONG); NTSYSAPI NTSTATUS WINAPI RtlLargeIntegerToChar(const ULONGLONG *,ULONG,ULONG,PCHAR); #endif @@ -338,5 +338,5 @@ index f88001f..4f16d24 100644 NTSYSAPI NTSTATUS CDECL wine_nt_to_unix_file_name( const UNICODE_STRING *nameW, ANSI_STRING *unix_name_ret, -- -2.3.3 +2.4.4 diff --git a/patches/ntdll-Vista_Threadpool/0018-ntdll-Implement-threadpool-wait-objects.patch b/patches/ntdll-Vista_Threadpool/0011-ntdll-Implement-threadpool-wait-objects.patch similarity index 88% rename from patches/ntdll-Vista_Threadpool/0018-ntdll-Implement-threadpool-wait-objects.patch rename to patches/ntdll-Vista_Threadpool/0011-ntdll-Implement-threadpool-wait-objects.patch index 03f9338f..2982c58f 100644 --- a/patches/ntdll-Vista_Threadpool/0018-ntdll-Implement-threadpool-wait-objects.patch +++ b/patches/ntdll-Vista_Threadpool/0011-ntdll-Implement-threadpool-wait-objects.patch @@ -1,4 +1,4 @@ -From 8e1c71f635b4005958e8f8b3a8b3bd654367f71c Mon Sep 17 00:00:00 2001 +From 008bb589716259fa962bdff580d5ec436bbf8ce4 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Wed, 4 Mar 2015 13:33:25 +0100 Subject: ntdll: Implement threadpool wait objects. @@ -9,10 +9,10 @@ Subject: ntdll: Implement threadpool wait objects. 2 files changed, 469 insertions(+), 11 deletions(-) diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec -index 21f39de..9093eb8 100644 +index 0f4374e..ffcf58d 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec -@@ -975,7 +975,7 @@ +@@ -977,7 +977,7 @@ # @ stub TpAllocJobNotification @ stdcall TpAllocPool(ptr ptr) @ stdcall TpAllocTimer(ptr ptr ptr) @@ -21,7 +21,7 @@ index 21f39de..9093eb8 100644 @ stdcall TpAllocWork(ptr ptr ptr ptr) # @ stub TpAlpcRegisterCompletionList # @ stub TpAlpcUnregisterCompletionList -@@ -1006,7 +1006,7 @@ +@@ -1008,7 +1008,7 @@ # @ stub TpReleaseJobNotification @ stdcall TpReleasePool(ptr) @ stdcall TpReleaseTimer(ptr) @@ -30,7 +30,7 @@ index 21f39de..9093eb8 100644 @ stdcall TpReleaseWork(ptr) # @ stub TpSetDefaultPoolMaxThreads # @ stub TpSetDefaultPoolStackInformation -@@ -1018,7 +1018,7 @@ +@@ -1020,7 +1020,7 @@ # @ stub TpSetPoolWorkerThreadIdleTimeout @ stdcall TpSetTimer(ptr ptr long long) # @ stub TpSetTimerEx @@ -39,7 +39,7 @@ index 21f39de..9093eb8 100644 # @ stub TpSetWaitEx @ stdcall TpSimpleTryPost(ptr ptr ptr) # @ stub TpStartAsyncIoOperation -@@ -1028,7 +1028,7 @@ +@@ -1030,7 +1030,7 @@ # @ stub TpWaitForIoCompletion # @ stub TpWaitForJobNotification @ stdcall TpWaitForTimer(ptr long) @@ -49,7 +49,7 @@ index 21f39de..9093eb8 100644 @ stdcall -ret64 VerSetConditionMask(int64 long long) @ stdcall WinSqmIsOptedIn() diff --git a/dlls/ntdll/threadpool.c b/dlls/ntdll/threadpool.c -index a973409..7df8cb1 100644 +index f4c9cba..f569506 100644 --- a/dlls/ntdll/threadpool.c +++ b/dlls/ntdll/threadpool.c @@ -137,6 +137,7 @@ struct timer_queue @@ -60,7 +60,7 @@ index a973409..7df8cb1 100644 /* internal threadpool representation */ struct threadpool -@@ -158,7 +159,8 @@ enum threadpool_objtype +@@ -159,7 +160,8 @@ enum threadpool_objtype { TP_OBJECT_TYPE_SIMPLE, TP_OBJECT_TYPE_WORK, @@ -70,7 +70,7 @@ index a973409..7df8cb1 100644 }; /* internal threadpool object representation */ -@@ -206,6 +208,17 @@ struct threadpool_object +@@ -207,6 +209,17 @@ struct threadpool_object LONG period; LONG window_length; } timer; @@ -88,7 +88,7 @@ index a973409..7df8cb1 100644 } u; }; -@@ -264,6 +277,38 @@ static RTL_CRITICAL_SECTION_DEBUG timerqueue_debug = +@@ -265,6 +278,38 @@ static RTL_CRITICAL_SECTION_DEBUG timerqueue_debug = 0, 0, { (DWORD_PTR)(__FILE__ ": timerqueue.cs") } }; @@ -127,21 +127,21 @@ index a973409..7df8cb1 100644 static inline struct threadpool *impl_from_TP_POOL( TP_POOL *pool ) { return (struct threadpool *)pool; -@@ -283,6 +328,13 @@ static inline struct threadpool_object *impl_from_TP_TIMER( TP_TIMER *timer ) +@@ -284,6 +329,13 @@ static inline struct threadpool_object *impl_from_TP_TIMER( TP_TIMER *timer ) return object; } +static inline struct threadpool_object *impl_from_TP_WAIT( TP_WAIT *wait ) +{ + struct threadpool_object *object = (struct threadpool_object *)wait; -+ assert( !object || object->type == TP_OBJECT_TYPE_WAIT ); ++ assert( object->type == TP_OBJECT_TYPE_WAIT ); + return object; +} + static inline struct threadpool_group *impl_from_TP_CLEANUP_GROUP( TP_CLEANUP_GROUP *group ) { return (struct threadpool_group *)group; -@@ -295,7 +347,8 @@ static inline struct threadpool_instance *impl_from_TP_CALLBACK_INSTANCE( TP_CAL +@@ -296,7 +348,8 @@ static inline struct threadpool_instance *impl_from_TP_CALLBACK_INSTANCE( TP_CAL static void CALLBACK threadpool_worker_proc( void *param ); static void CALLBACK timerqueue_thread_proc( void *param ); @@ -151,7 +151,7 @@ index a973409..7df8cb1 100644 static void tp_object_shutdown( struct threadpool_object *object ); static BOOL tp_object_release( struct threadpool_object *object ); static struct threadpool *default_threadpool = NULL; -@@ -1349,7 +1402,7 @@ update_timer: +@@ -1350,7 +1403,7 @@ update_timer: RtlLeaveCriticalSection( &timerqueue.cs ); if (submit_timer) @@ -160,7 +160,7 @@ index a973409..7df8cb1 100644 } static void CALLBACK timerqueue_thread_proc( void *param ) -@@ -1376,7 +1429,7 @@ static void CALLBACK timerqueue_thread_proc( void *param ) +@@ -1377,7 +1430,7 @@ static void CALLBACK timerqueue_thread_proc( void *param ) /* Queue a new callback in one of the worker threads */ list_remove( &timer->u.timer.timer_entry ); @@ -169,7 +169,7 @@ index a973409..7df8cb1 100644 /* Requeue the timer, except its marked for shutdown */ if (!timer->shutdown && timer->u.timer.period) -@@ -1442,6 +1495,301 @@ static void CALLBACK timerqueue_thread_proc( void *param ) +@@ -1443,6 +1496,301 @@ static void CALLBACK timerqueue_thread_proc( void *param ) RtlLeaveCriticalSection( &timerqueue.cs ); } @@ -468,28 +468,28 @@ index a973409..7df8cb1 100644 + RtlFreeHeap( GetProcessHeap(), 0, bucket ); +} + - /* allocate a new threadpool (with at least one worker thread) */ - static NTSTATUS tp_threadpool_alloc( struct threadpool **out ) - { -@@ -1640,7 +1988,7 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa - * to the cleanup group. As soon as the cleanup group members are released ->shutdown + /*********************************************************************** + * tp_threadpool_alloc (internal) + * +@@ -1710,7 +2058,7 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa * will be set, and tp_object_submit would fail with an assertion. */ - if (simple_cb) + + if (is_simple_callback) - tp_object_submit( object ); + tp_object_submit( object, FALSE ); if (object->group) { -@@ -1661,7 +2009,7 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa - } - - /* submits an object to a threadpool */ +@@ -1736,7 +2084,7 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa + * Submits a threadpool object to the associcated threadpool. This + * function has to be VOID because TpPostWork can never fail on Windows. + */ -static void tp_object_submit( struct threadpool_object *object ) +static void tp_object_submit( struct threadpool_object *object, BOOL success ) { struct threadpool *pool = object->pool; - -@@ -1696,6 +2044,10 @@ out: + NTSTATUS status = STATUS_UNSUCCESSFUL; +@@ -1766,6 +2114,10 @@ static void tp_object_submit( struct threadpool_object *object ) if (!object->num_pending_callbacks++) list_add_tail( &pool->pool, &object->pool_entry ); @@ -497,20 +497,20 @@ index a973409..7df8cb1 100644 + if (object->type == TP_OBJECT_TYPE_WAIT && success) + object->u.wait.signaled++; + - RtlLeaveCriticalSection( &pool->cs ); - } - -@@ -1714,6 +2066,9 @@ static void tp_object_cancel( struct threadpool_object *object, BOOL group_cance + /* No new thread started - wake up one existing thread. */ + if (status != STATUS_SUCCESS) + { +@@ -1793,6 +2145,9 @@ static void tp_object_cancel( struct threadpool_object *object, BOOL group_cance + object->num_pending_callbacks = 0; list_remove( &object->pool_entry ); } - ++ + if (object->type == TP_OBJECT_TYPE_WAIT) + object->u.wait.signaled = 0; -+ RtlLeaveCriticalSection( &pool->cs ); /* Execute group cancellation callback if defined, and if this was actually a group cancel. */ -@@ -1747,6 +2102,8 @@ static void tp_object_shutdown( struct threadpool_object *object ) +@@ -1833,6 +2188,8 @@ static void tp_object_shutdown( struct threadpool_object *object ) { if (object->type == TP_OBJECT_TYPE_TIMER) tp_timerqueue_release( object ); @@ -519,15 +519,15 @@ index a973409..7df8cb1 100644 object->shutdown = TRUE; } -@@ -1912,6 +2269,7 @@ static void CALLBACK threadpool_worker_proc( void *param ) +@@ -1886,6 +2243,7 @@ static void CALLBACK threadpool_worker_proc( void *param ) struct threadpool_instance instance; TP_CALLBACK_INSTANCE *cb_instance = (TP_CALLBACK_INSTANCE *)&instance; struct threadpool *pool = param; + TP_WAIT_RESULT wait_result; LARGE_INTEGER timeout; struct list *ptr; - -@@ -1929,6 +2287,18 @@ static void CALLBACK threadpool_worker_proc( void *param ) + NTSTATUS status; +@@ -1906,6 +2264,18 @@ static void CALLBACK threadpool_worker_proc( void *param ) if (--object->num_pending_callbacks) list_add_tail( &pool->pool, &object->pool_entry ); @@ -546,7 +546,7 @@ index a973409..7df8cb1 100644 /* Leave critical section and do the actual callback. */ object->num_running_callbacks++; pool->num_busy_workers++; -@@ -1964,6 +2334,15 @@ static void CALLBACK threadpool_worker_proc( void *param ) +@@ -1952,6 +2322,15 @@ static void CALLBACK threadpool_worker_proc( void *param ) break; } @@ -562,7 +562,7 @@ index a973409..7df8cb1 100644 default: assert(0); break; -@@ -2073,6 +2452,41 @@ NTSTATUS WINAPI TpAllocTimer( TP_TIMER **out, PTP_TIMER_CALLBACK callback, PVOID +@@ -2092,6 +2471,46 @@ NTSTATUS WINAPI TpAllocTimer( TP_TIMER **out, PTP_TIMER_CALLBACK callback, PVOID } /*********************************************************************** @@ -575,21 +575,26 @@ index a973409..7df8cb1 100644 + struct threadpool *pool; + NTSTATUS status; + -+ TRACE("%p %p %p %p\n", out, callback, userdata, environment); -+ -+ if (!(pool = get_threadpool( environment ))) -+ return STATUS_NO_MEMORY; ++ 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_WAIT; + object->u.wait.callback = callback; + + status = tp_waitqueue_acquire( object ); + if (status) + { ++ tp_threadpool_unlock( pool ); + RtlFreeHeap( GetProcessHeap(), 0, object ); + return status; + } @@ -604,16 +609,16 @@ index a973409..7df8cb1 100644 * TpAllocWork (NTDLL.@) */ NTSTATUS WINAPI TpAllocWork( TP_WORK **out, PTP_WORK_CALLBACK callback, PVOID userdata, -@@ -2248,7 +2662,7 @@ VOID WINAPI TpPostWork( TP_WORK *work ) +@@ -2285,7 +2704,7 @@ VOID WINAPI TpPostWork( TP_WORK *work ) - if (this) - { -- tp_object_submit( this ); -+ tp_object_submit( this, FALSE ); - } + TRACE( "%p\n", work ); + +- tp_object_submit( this ); ++ tp_object_submit( this, FALSE ); } -@@ -2362,6 +2776,21 @@ VOID WINAPI TpReleaseTimer( TP_TIMER *timer ) + /*********************************************************************** +@@ -2389,6 +2808,19 @@ VOID WINAPI TpReleaseTimer( TP_TIMER *timer ) } /*********************************************************************** @@ -622,20 +627,18 @@ index a973409..7df8cb1 100644 +VOID WINAPI TpReleaseWait( TP_WAIT *wait ) +{ + struct threadpool_object *this = impl_from_TP_WAIT( wait ); -+ TRACE("%p\n", wait); + -+ if (this) -+ { -+ tp_object_shutdown( this ); -+ tp_object_release( this ); -+ } ++ TRACE( "%p\n", wait ); ++ ++ tp_object_shutdown( this ); ++ tp_object_release( this ); +} + +/*********************************************************************** * TpReleaseWork (NTDLL.@) */ VOID WINAPI TpReleaseWork( TP_WORK *work ) -@@ -2426,6 +2855,20 @@ VOID WINAPI TpSetTimer( TP_TIMER *timer, LARGE_INTEGER *timeout, LONG period, LO +@@ -2464,6 +2896,18 @@ VOID WINAPI TpSetTimer( TP_TIMER *timer, LARGE_INTEGER *timeout, LONG period, LO } /*********************************************************************** @@ -644,19 +647,17 @@ index a973409..7df8cb1 100644 +VOID WINAPI TpSetWait( TP_WAIT *wait, HANDLE handle, LARGE_INTEGER *timeout ) +{ + struct threadpool_object *this = impl_from_TP_WAIT( wait ); -+ TRACE("%p %p %p\n", wait, handle, timeout); + -+ if (this) -+ { -+ tp_waitqueue_update_wait( this, handle, timeout ); -+ } ++ TRACE( "%p %p %p\n", wait, handle, timeout ); ++ ++ tp_waitqueue_update_wait( this, handle, timeout ); +} + +/*********************************************************************** * TpSimpleTryPost (NTDLL.@) */ NTSTATUS WINAPI TpSimpleTryPost( PTP_SIMPLE_CALLBACK callback, PVOID userdata, -@@ -2466,6 +2909,21 @@ VOID WINAPI TpWaitForTimer( TP_TIMER *timer, BOOL cancel_pending ) +@@ -2508,6 +2952,20 @@ VOID WINAPI TpWaitForTimer( TP_TIMER *timer, BOOL cancel_pending ) } /*********************************************************************** @@ -665,13 +666,12 @@ index a973409..7df8cb1 100644 +VOID WINAPI TpWaitForWait( TP_WAIT *wait, BOOL cancel_pending ) +{ + struct threadpool_object *this = impl_from_TP_WAIT( wait ); -+ TRACE("%p %d\n", wait, cancel_pending); -+ if (this) -+ { -+ if (cancel_pending) -+ tp_object_cancel( this, FALSE, NULL ); -+ tp_object_wait( this ); -+ } ++ ++ TRACE( "%p %d\n", wait, cancel_pending ); ++ ++ if (cancel_pending) ++ tp_object_cancel( this, FALSE, NULL ); ++ tp_object_wait( this ); +} + +/*********************************************************************** @@ -679,5 +679,5 @@ index a973409..7df8cb1 100644 */ VOID WINAPI TpWaitForWork( TP_WORK *work, BOOL cancel_pending ) -- -2.3.5 +2.4.4 diff --git a/patches/ntdll-Vista_Threadpool/0019-ntdll-tests-Add-tests-for-threadpool-wait-objects.patch b/patches/ntdll-Vista_Threadpool/0012-ntdll-tests-Add-tests-for-threadpool-wait-objects.patch similarity index 99% rename from patches/ntdll-Vista_Threadpool/0019-ntdll-tests-Add-tests-for-threadpool-wait-objects.patch rename to patches/ntdll-Vista_Threadpool/0012-ntdll-tests-Add-tests-for-threadpool-wait-objects.patch index 9408d85e..910e204f 100644 --- a/patches/ntdll-Vista_Threadpool/0019-ntdll-tests-Add-tests-for-threadpool-wait-objects.patch +++ b/patches/ntdll-Vista_Threadpool/0012-ntdll-tests-Add-tests-for-threadpool-wait-objects.patch @@ -1,4 +1,4 @@ -From 8f4a1b78d16cd1977ef52c55b0729db006fcfb2b Mon Sep 17 00:00:00 2001 +From 0f5fd3ad8c585b98f2754738fb9a7bb0e9b83708 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Fri, 6 Feb 2015 20:09:41 +0100 Subject: ntdll/tests: Add tests for threadpool wait objects. @@ -8,7 +8,7 @@ Subject: ntdll/tests: Add tests for threadpool wait objects. 1 file changed, 287 insertions(+) diff --git a/dlls/ntdll/tests/threadpool.c b/dlls/ntdll/tests/threadpool.c -index b44b0f5..0e845ce 100644 +index 76db2d0..368692b 100644 --- a/dlls/ntdll/tests/threadpool.c +++ b/dlls/ntdll/tests/threadpool.c @@ -770,6 +770,291 @@ static void test_tp_window_length(void) @@ -313,5 +313,5 @@ index b44b0f5..0e845ce 100644 /* FIXME: Make sure worker threads have terminated before. */ Sleep(100); -- -2.4.0 +2.4.4 diff --git a/patches/ntdll-Vista_Threadpool/0020-kernel32-Forward-threadpool-wait-functions-to-ntdll.patch b/patches/ntdll-Vista_Threadpool/0013-kernel32-Forward-threadpool-wait-functions-to-ntdll.patch similarity index 94% rename from patches/ntdll-Vista_Threadpool/0020-kernel32-Forward-threadpool-wait-functions-to-ntdll.patch rename to patches/ntdll-Vista_Threadpool/0013-kernel32-Forward-threadpool-wait-functions-to-ntdll.patch index c1ffb3b8..1ba80e7e 100644 --- a/patches/ntdll-Vista_Threadpool/0020-kernel32-Forward-threadpool-wait-functions-to-ntdll.patch +++ b/patches/ntdll-Vista_Threadpool/0013-kernel32-Forward-threadpool-wait-functions-to-ntdll.patch @@ -1,4 +1,4 @@ -From bd2b6f3c1602f5bd24781ae12052994cae0bad73 Mon Sep 17 00:00:00 2001 +From 2427c8fb3757a84085d22d176f9f6e797ea64498 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Fri, 6 Feb 2015 20:24:27 +0100 Subject: kernel32: Forward threadpool wait functions to ntdll. @@ -10,7 +10,7 @@ Subject: kernel32: Forward threadpool wait functions to ntdll. 3 files changed, 51 insertions(+), 4 deletions(-) diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec -index f65f894..4eba956 100644 +index 337b339..146db0f 100644 --- a/dlls/kernel32/kernel32.spec +++ b/dlls/kernel32/kernel32.spec @@ -233,7 +233,7 @@ @@ -31,7 +31,7 @@ index f65f894..4eba956 100644 @ stdcall CreateThreadpoolWork(ptr ptr ptr) @ stdcall CreateTimerQueue () @ stdcall CreateTimerQueueTimer(ptr long ptr ptr long long long) -@@ -1456,7 +1456,7 @@ +@@ -1457,7 +1457,7 @@ @ stdcall SetThreadpoolThreadMaximum(ptr long) ntdll.TpSetPoolMaxThreads @ stdcall SetThreadpoolThreadMinimum(ptr long) ntdll.TpSetPoolMinThreads @ stdcall SetThreadpoolTimer(ptr ptr long long) @@ -40,7 +40,7 @@ index f65f894..4eba956 100644 @ stdcall SetTimeZoneInformation(ptr) @ stub SetTimerQueueTimer # @ stub -arch=x86_64 SetUmsThreadInformation -@@ -1571,7 +1571,7 @@ +@@ -1572,7 +1572,7 @@ @ stdcall WaitForSingleObjectEx(long long long) # @ stub WaitForThreadpoolIoCallbacks @ stdcall WaitForThreadpoolTimerCallbacks(ptr long) ntdll.TpWaitForTimer @@ -108,10 +108,10 @@ index 945fe0b..89b0b60 100644 + TpSetWait( wait, handle, due_time ? &timeout : NULL ); +} diff --git a/include/winternl.h b/include/winternl.h -index 4f16d24..ee38c48 100644 +index e1707fd..7ab1bd8 100644 --- a/include/winternl.h +++ b/include/winternl.h -@@ -2601,6 +2601,7 @@ NTSYSAPI NTSTATUS WINAPI RtlLargeIntegerToChar(const ULONGLONG *,ULONG,ULONG,PC +@@ -2621,6 +2621,7 @@ NTSYSAPI NTSTATUS WINAPI RtlLargeIntegerToChar(const ULONGLONG *,ULONG,ULONG,PC NTSYSAPI NTSTATUS WINAPI TpAllocCleanupGroup(TP_CLEANUP_GROUP **); NTSYSAPI NTSTATUS WINAPI TpAllocPool(TP_POOL **,PVOID); NTSYSAPI NTSTATUS WINAPI TpAllocTimer(TP_TIMER **,PTP_TIMER_CALLBACK,PVOID,TP_CALLBACK_ENVIRON *); @@ -119,7 +119,7 @@ index 4f16d24..ee38c48 100644 NTSYSAPI NTSTATUS WINAPI TpAllocWork(TP_WORK **,PTP_WORK_CALLBACK,PVOID,TP_CALLBACK_ENVIRON *); NTSYSAPI void WINAPI TpCallbackLeaveCriticalSectionOnCompletion(TP_CALLBACK_INSTANCE *,RTL_CRITICAL_SECTION *); NTSYSAPI NTSTATUS WINAPI TpCallbackMayRunLong(TP_CALLBACK_INSTANCE *); -@@ -2615,12 +2616,15 @@ NTSYSAPI void WINAPI TpReleaseCleanupGroup(TP_CLEANUP_GROUP *); +@@ -2635,12 +2636,15 @@ NTSYSAPI void WINAPI TpReleaseCleanupGroup(TP_CLEANUP_GROUP *); NTSYSAPI void WINAPI TpReleaseCleanupGroupMembers(TP_CLEANUP_GROUP *,BOOL,PVOID); NTSYSAPI void WINAPI TpReleasePool(TP_POOL *); NTSYSAPI void WINAPI TpReleaseTimer(TP_TIMER *); @@ -136,5 +136,5 @@ index 4f16d24..ee38c48 100644 /* Wine internal functions */ -- -2.3.3 +2.4.4 diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 0943fb43..5c30e23d 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -55,7 +55,7 @@ version() echo "Copyright (C) 2014-2015 the Wine Staging project authors." echo "" echo "Patchset to be applied on upstream Wine:" - echo " commit 6b205e41cf0798fd6dff7c37e9b250fc885cf792" + echo " commit 7a3c9889e38ede659230a66a167b82c024f0dc85" echo "" } @@ -3701,34 +3701,20 @@ fi # | dlls/ntdll/tests/threadpool.c, dlls/ntdll/threadpool.c, include/winternl.h # | if test "$enable_ntdll_Vista_Threadpool" -eq 1; then - patch_apply ntdll-Vista_Threadpool/0001-ntdll-Implement-TpSimpleTryPost-and-basic-threadpool.patch - patch_apply ntdll-Vista_Threadpool/0002-ntdll-Implement-TpSetPool-Min-Max-Threads.-v2.patch - patch_apply ntdll-Vista_Threadpool/0003-ntdll-Implement-threadpool-cleanup-group-functions.patch - patch_apply ntdll-Vista_Threadpool/0004-ntdll-tests-Add-tests-for-TpAllocCleanupGroup-and-re.patch - patch_apply ntdll-Vista_Threadpool/0005-ntdll-Implement-threadpool-work-item-functions.patch - patch_apply ntdll-Vista_Threadpool/0006-ntdll-tests-Add-basic-tests-for-threadpool-work-item.patch - patch_apply ntdll-Vista_Threadpool/0007-ntdll-tests-Add-threadpool-scheduler-tests-for-work-.patch - patch_apply ntdll-Vista_Threadpool/0008-ntdll-Add-support-for-threadpool-group-cancel-callba.patch - patch_apply ntdll-Vista_Threadpool/0009-ntdll-Add-support-for-threadpool-finalization-callba.patch - patch_apply ntdll-Vista_Threadpool/0010-ntdll-Implement-threadpool-RaceDll-environment-varia.patch - patch_apply ntdll-Vista_Threadpool/0011-ntdll-Implement-TpCallbackMayRunLong-and-instance-st.patch - patch_apply ntdll-Vista_Threadpool/0012-ntdll-Implement-TpDisassociateCallback.patch - patch_apply ntdll-Vista_Threadpool/0013-ntdll-Implement-various-TpCallback-OnCompletion-func.patch - patch_apply ntdll-Vista_Threadpool/0014-ntdll-Add-remaining-threadpool-functions-to-specfile.patch - patch_apply ntdll-Vista_Threadpool/0015-ntdll-Implement-threadpool-timer-functions.-rev-2.patch - patch_apply ntdll-Vista_Threadpool/0016-ntdll-tests-Add-tests-for-Tp-threadpool-functions.patch - patch_apply ntdll-Vista_Threadpool/0017-kernel32-Forward-various-threadpool-functions-to-ntd.patch - patch_apply ntdll-Vista_Threadpool/0018-ntdll-Implement-threadpool-wait-objects.patch - patch_apply ntdll-Vista_Threadpool/0019-ntdll-tests-Add-tests-for-threadpool-wait-objects.patch - patch_apply ntdll-Vista_Threadpool/0020-kernel32-Forward-threadpool-wait-functions-to-ntdll.patch + patch_apply ntdll-Vista_Threadpool/0001-ntdll-Add-support-for-threadpool-group-cancel-callba.patch + patch_apply ntdll-Vista_Threadpool/0002-ntdll-Add-support-for-threadpool-finalization-callba.patch + patch_apply ntdll-Vista_Threadpool/0003-ntdll-Implement-threadpool-RaceDll-environment-varia.patch + patch_apply ntdll-Vista_Threadpool/0004-ntdll-Implement-TpCallbackMayRunLong-and-instance-st.patch + patch_apply ntdll-Vista_Threadpool/0005-ntdll-Implement-TpDisassociateCallback.patch + patch_apply ntdll-Vista_Threadpool/0006-ntdll-Implement-various-TpCallback-OnCompletion-func.patch + patch_apply ntdll-Vista_Threadpool/0007-ntdll-Add-remaining-threadpool-functions-to-specfile.patch + patch_apply ntdll-Vista_Threadpool/0008-ntdll-Implement-threadpool-timer-functions.-rev-2.patch + patch_apply ntdll-Vista_Threadpool/0009-ntdll-tests-Add-tests-for-Tp-threadpool-functions.patch + patch_apply ntdll-Vista_Threadpool/0010-kernel32-Forward-various-threadpool-functions-to-ntd.patch + patch_apply ntdll-Vista_Threadpool/0011-ntdll-Implement-threadpool-wait-objects.patch + patch_apply ntdll-Vista_Threadpool/0012-ntdll-tests-Add-tests-for-threadpool-wait-objects.patch + patch_apply ntdll-Vista_Threadpool/0013-kernel32-Forward-threadpool-wait-functions-to-ntdll.patch ( - echo '+ { "Sebastian Lackner", "ntdll: Implement TpSimpleTryPost and basic threadpool infrastructure.", 1 },'; - echo '+ { "Sebastian Lackner", "ntdll: Implement TpSetPool[Min|Max]Threads.", 2 },'; - echo '+ { "Sebastian Lackner", "ntdll: Implement threadpool cleanup group functions.", 1 },'; - echo '+ { "Sebastian Lackner", "ntdll/tests: Add tests for TpAllocCleanupGroup and related functions.", 1 },'; - echo '+ { "Sebastian Lackner", "ntdll: Implement threadpool work item functions.", 1 },'; - echo '+ { "Sebastian Lackner", "ntdll/tests: Add basic tests for threadpool work items.", 1 },'; - echo '+ { "Sebastian Lackner", "ntdll/tests: Add threadpool scheduler tests for work items.", 1 },'; echo '+ { "Sebastian Lackner", "ntdll: Add support for threadpool group cancel callback.", 1 },'; echo '+ { "Sebastian Lackner", "ntdll: Add support for threadpool finalization callback.", 1 },'; echo '+ { "Sebastian Lackner", "ntdll: Implement threadpool RaceDll environment variable.", 1 },';