From d86ab363695d1b9a6e07e4ec1d824552b3d4d666 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Mon, 22 Aug 2016 21:52:23 +0200 Subject: [PATCH] Rebase against 90173ce448e5afe55627c2cbece28fb4f6bae99d. [ntdll-ThreadpoolCleanupGroup] Removed patches to fix multiple bugs related to threadpool cleanup groups and cancel callbacks (accepted upstream). --- ...-dll-and-add-stub-for-QuirkIsEnabled.patch | 12 +- ...nel32-package-current-l1-1-0-Add-dll.patch | 14 +- .../definition | 1 - ...longer-waits-to-reduce-risk-of-rando.patch | 134 ------ ...elease-threadpool-objects-while-wait.patch | 142 ------ ...tests-for-releasing-threadpool-objec.patch | 148 ------- ...-cancel-callback-with-the-correct-ar.patch | 151 ------- ...el-callbacks-should-be-executed-afte.patch | 193 -------- ...l-group-cancel-callback-for-finished.patch | 114 ----- ...synchronization-for-CloseThreadpoolC.patch | 76 ---- .../ntdll-ThreadpoolCleanupGroup/definition | 1 - ...ent-metafile-loading-using-gdi32-ins.patch | 419 ------------------ patches/patchinstall.sh | 133 ++---- staging/VERSION | 2 +- 14 files changed, 60 insertions(+), 1480 deletions(-) delete mode 100644 patches/ntdll-ThreadpoolCleanupGroup/0001-ntdll-tests-Use-longer-waits-to-reduce-risk-of-rando.patch delete mode 100644 patches/ntdll-ThreadpoolCleanupGroup/0002-ntdll-Allow-to-release-threadpool-objects-while-wait.patch delete mode 100644 patches/ntdll-ThreadpoolCleanupGroup/0003-ntdll-tests-Add-tests-for-releasing-threadpool-objec.patch delete mode 100644 patches/ntdll-ThreadpoolCleanupGroup/0004-ntdll-Call-group-cancel-callback-with-the-correct-ar.patch delete mode 100644 patches/ntdll-ThreadpoolCleanupGroup/0005-ntdll-Group-cancel-callbacks-should-be-executed-afte.patch delete mode 100644 patches/ntdll-ThreadpoolCleanupGroup/0006-ntdll-Do-not-call-group-cancel-callback-for-finished.patch delete mode 100644 patches/ntdll-ThreadpoolCleanupGroup/0007-services-Remove-synchronization-for-CloseThreadpoolC.patch delete mode 100644 patches/ntdll-ThreadpoolCleanupGroup/definition delete mode 100644 patches/oleaut32-OLEPictureImpl_SaveAsFile/0001-gdiplus-Reimplement-metafile-loading-using-gdi32-ins.patch diff --git a/patches/api-ms-win-Stub_DLLs/0001-kernelbase-Add-dll-and-add-stub-for-QuirkIsEnabled.patch b/patches/api-ms-win-Stub_DLLs/0001-kernelbase-Add-dll-and-add-stub-for-QuirkIsEnabled.patch index 4c2d5bfe..7cb9ae44 100644 --- a/patches/api-ms-win-Stub_DLLs/0001-kernelbase-Add-dll-and-add-stub-for-QuirkIsEnabled.patch +++ b/patches/api-ms-win-Stub_DLLs/0001-kernelbase-Add-dll-and-add-stub-for-QuirkIsEnabled.patch @@ -1,4 +1,4 @@ -From 446107bd1bda89cfdb656dd1f0e06dcb328c00ed Mon Sep 17 00:00:00 2001 +From 0d41f28599a8b37e38a09a2d41ded554b7f05baa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=BCller?= Date: Fri, 15 Jan 2016 13:01:15 +0100 Subject: kernelbase: Add dll and add stub for QuirkIsEnabled. @@ -22,7 +22,7 @@ index b9caed0..2beb34b 100644 +C_SRCS = \ + misc.c diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec -index 23ca440..19cf953 100644 +index bef97a0..cd33ef8 100644 --- a/dlls/kernelbase/kernelbase.spec +++ b/dlls/kernelbase/kernelbase.spec @@ -1,3 +1,6 @@ @@ -250,7 +250,7 @@ index 23ca440..19cf953 100644 @ stdcall DebugBreak() kernel32.DebugBreak @ stdcall DecodePointer(ptr) kernel32.DecodePointer +@ stub DecodeRemotePointer - @ stub DecodeSystemPointer + @ stdcall DecodeSystemPointer(ptr) kernel32.DecodeSystemPointer @ stdcall DefineDosDeviceW(long wstr wstr) kernel32.DefineDosDeviceW +@ stdcall DelayLoadFailureHook(str str) kernel32.DelayLoadFailureHook +@ stub DelayLoadFailureHookLookup @@ -294,7 +294,7 @@ index 23ca440..19cf953 100644 +@ stub EmptyWorkingSet @ stdcall EncodePointer(ptr) kernel32.EncodePointer +@ stub EncodeRemotePointer - @ stub EncodeSystemPointer + @ stdcall EncodeSystemPointer(ptr) kernel32.EncodeSystemPointer +@ stub EnterCriticalPolicySectionInternal @ stdcall EnterCriticalSection(ptr) kernel32.EnterCriticalSection +@ stub EnterSynchronizationBarrier @@ -1770,10 +1770,10 @@ index 6b6ead2..7c2a9d1 100644 422 stdcall -noname SHGlobalCounterCreateNamedA(str long) 423 stdcall -noname SHGlobalCounterCreateNamedW(wstr long) diff --git a/tools/make_specfiles b/tools/make_specfiles -index d658f30..c1a0f15 100755 +index 947cde7..a102a15 100755 --- a/tools/make_specfiles +++ b/tools/make_specfiles -@@ -195,6 +195,7 @@ my @dll_groups = +@@ -196,6 +196,7 @@ my @dll_groups = [ "kernel32", "advapi32", diff --git a/patches/api-ms-win-Stub_DLLs/0021-ext-ms-win-kernel32-package-current-l1-1-0-Add-dll.patch b/patches/api-ms-win-Stub_DLLs/0021-ext-ms-win-kernel32-package-current-l1-1-0-Add-dll.patch index c5b12b29..8876bdf8 100644 --- a/patches/api-ms-win-Stub_DLLs/0021-ext-ms-win-kernel32-package-current-l1-1-0-Add-dll.patch +++ b/patches/api-ms-win-Stub_DLLs/0021-ext-ms-win-kernel32-package-current-l1-1-0-Add-dll.patch @@ -1,4 +1,4 @@ -From 88367d179496bb178f97591000ef5e56e58a9322 Mon Sep 17 00:00:00 2001 +From 5989f92d5a873732acb8cb9af4011ce7e145bbb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=BCller?= Date: Sat, 23 Jan 2016 21:13:02 +0100 Subject: ext-ms-win-kernel32-package-current-l1-1-0: Add dll. @@ -13,10 +13,10 @@ Subject: ext-ms-win-kernel32-package-current-l1-1-0: Add dll. create mode 100644 dlls/ext-ms-win-kernel32-package-current-l1-1-0/ext-ms-win-kernel32-package-current-l1-1-0.spec diff --git a/configure.ac b/configure.ac -index bb63b0d..e7c55db 100644 +index d2abe1d..dc1b078 100644 --- a/configure.ac +++ b/configure.ac -@@ -2939,6 +2939,7 @@ WINE_CONFIG_DLL(explorerframe,,[clean]) +@@ -2958,6 +2958,7 @@ WINE_CONFIG_DLL(explorerframe,,[clean]) WINE_CONFIG_TEST(dlls/explorerframe/tests) WINE_CONFIG_DLL(ext-ms-win-appmodel-usercontext-l1-1-0) WINE_CONFIG_DLL(ext-ms-win-gdi-devcaps-l1-1-0) @@ -40,17 +40,17 @@ index 0000000..2156c27 +@ stdcall GetCurrentPackageId(ptr ptr) kernel32.GetCurrentPackageId +@ stub GetCurrentPackageInfo diff --git a/tools/make_specfiles b/tools/make_specfiles -index b364446..5b2418b 100755 +index 1337fca..756ae00 100755 --- a/tools/make_specfiles +++ b/tools/make_specfiles -@@ -214,6 +214,7 @@ my @dll_groups = - "api-ms-win-core-wow64-l1-1-0", +@@ -180,6 +180,7 @@ my @dll_groups = "api-ms-win-core-xstate-l2-1-0", "api-ms-win-core-errorhandling-l1-1-2", + "api-ms-win-core-util-l1-1-0", + "ext-ms-win-kernel32-package-current-l1-1-0", ], [ "kernel32", -- -2.6.4 +2.9.0 diff --git a/patches/gdiplus-GdipCreateMetafileFromStream/definition b/patches/gdiplus-GdipCreateMetafileFromStream/definition index 3e18d312..71374ab3 100644 --- a/patches/gdiplus-GdipCreateMetafileFromStream/definition +++ b/patches/gdiplus-GdipCreateMetafileFromStream/definition @@ -1,3 +1,2 @@ Fixes: [40325] Implement GdipCreateMetafileFromStream Fixes: [27415] Implement GdipGetMetafileHeaderFromMetafile -Depends: oleaut32-OLEPictureImpl_SaveAsFile diff --git a/patches/ntdll-ThreadpoolCleanupGroup/0001-ntdll-tests-Use-longer-waits-to-reduce-risk-of-rando.patch b/patches/ntdll-ThreadpoolCleanupGroup/0001-ntdll-tests-Use-longer-waits-to-reduce-risk-of-rando.patch deleted file mode 100644 index d98a1669..00000000 --- a/patches/ntdll-ThreadpoolCleanupGroup/0001-ntdll-tests-Use-longer-waits-to-reduce-risk-of-rando.patch +++ /dev/null @@ -1,134 +0,0 @@ -From a6213f025a63ad3b2a086c028dae1ff30892af5a Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Sat, 20 Aug 2016 21:18:33 +0200 -Subject: ntdll/tests: Use longer waits to reduce risk of random failures on - the testbot. - -Signed-off-by: Sebastian Lackner ---- - dlls/ntdll/tests/threadpool.c | 32 +++++++++++++++++--------------- - 1 file changed, 17 insertions(+), 15 deletions(-) - -diff --git a/dlls/ntdll/tests/threadpool.c b/dlls/ntdll/tests/threadpool.c -index 1d8b1f9..9b4b522 100644 ---- a/dlls/ntdll/tests/threadpool.c -+++ b/dlls/ntdll/tests/threadpool.c -@@ -579,14 +579,14 @@ static void test_tp_simple(void) - static void CALLBACK work_cb(TP_CALLBACK_INSTANCE *instance, void *userdata, TP_WORK *work) - { - trace("Running work callback\n"); -- Sleep(10); -+ Sleep(100); - InterlockedIncrement((LONG *)userdata); - } - - static void CALLBACK work2_cb(TP_CALLBACK_INSTANCE *instance, void *userdata, TP_WORK *work) - { - trace("Running work2 callback\n"); -- Sleep(10); -+ Sleep(100); - InterlockedExchangeAdd((LONG *)userdata, 0x10000); - } - -@@ -599,11 +599,12 @@ static void test_tp_work(void) - LONG userdata; - int i; - -- /* allocate new threadpool */ -+ /* allocate new threadpool with only one thread */ - pool = NULL; - status = pTpAllocPool(&pool, NULL); - ok(!status, "TpAllocPool failed with status %x\n", status); - ok(pool != NULL, "expected pool != NULL\n"); -+ pTpSetPoolMaxThreads(pool, 1); - - /* allocate new work item */ - work = NULL; -@@ -614,12 +615,12 @@ static void test_tp_work(void) - ok(!status, "TpAllocWork failed with status %x\n", status); - ok(work != NULL, "expected work != NULL\n"); - -- /* post 10 identical work items at once */ -+ /* post 5 identical work items at once */ - userdata = 0; -- for (i = 0; i < 10; i++) -+ for (i = 0; i < 5; i++) - pTpPostWork(work); - pTpWaitForWork(work, FALSE); -- ok(userdata == 10, "expected userdata = 10, got %u\n", userdata); -+ ok(userdata == 5, "expected userdata = 5, got %u\n", userdata); - - /* add more tasks and cancel them immediately */ - userdata = 0; -@@ -643,13 +644,11 @@ static void test_tp_work_scheduler(void) - LONG userdata; - int i; - -- /* allocate new threadpool */ -+ /* allocate new threadpool with only one thread */ - 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 */ -@@ -683,7 +682,7 @@ static void test_tp_work_scheduler(void) - pTpPostWork(work); - for (i = 0; i < 10; i++) - pTpPostWork(work2); -- Sleep(30); -+ Sleep(500); - pTpWaitForWork(work, TRUE); - pTpWaitForWork(work2, TRUE); - ok(userdata & 0xffff, "expected userdata & 0xffff != 0, got %u\n", userdata & 0xffff); -@@ -691,14 +690,14 @@ static void test_tp_work_scheduler(void) - - /* test TpReleaseCleanupGroupMembers on a work item */ - userdata = 0; -- for (i = 0; i < 100; i++) -- pTpPostWork(work); - for (i = 0; i < 10; i++) -+ pTpPostWork(work); -+ for (i = 0; i < 3; 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); -+ ok((userdata & 0xffff) < 10, "expected userdata & 0xffff < 10, got %u\n", userdata & 0xffff); -+ ok((userdata >> 16) == 3, "expected userdata >> 16 == 3, got %u\n", userdata >> 16); - - /* cleanup */ - pTpReleaseWork(work); -@@ -720,6 +719,7 @@ static void CALLBACK group_cancel_cb(TP_CALLBACK_INSTANCE *instance, void *userd - ok(status == STATUS_TOO_MANY_THREADS || broken(status == 1) /* Win Vista / 2008 */, - "expected STATUS_TOO_MANY_THREADS, got %08x\n", status); - -+ ReleaseSemaphore(semaphores[1], 1, NULL); - result = WaitForSingleObject(semaphores[0], 1000); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); - ReleaseSemaphore(semaphores[1], 1, NULL); -@@ -781,6 +781,8 @@ static void test_tp_group_cancel(void) - environment.Pool = pool; - status = pTpSimpleTryPost(group_cancel_cb, semaphores, &environment); - ok(!status, "TpSimpleTryPost failed with status %x\n", status); -+ result = WaitForSingleObject(semaphores[1], 1000); -+ ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); - - memset(&environment, 0, sizeof(environment)); - environment.Version = 1; -@@ -816,7 +818,7 @@ static void test_tp_group_cancel(void) - /* check if we get multiple cancellation callbacks */ - group_cancel_tid = 0xdeadbeef; - pTpReleaseCleanupGroupMembers(group, TRUE, &userdata2); -- ok(userdata <= 8, "expected userdata <= 8, got %u\n", userdata); -+ ok(userdata <= 5, "expected userdata <= 5, got %u\n", userdata); - ok(userdata2 == 1, "expected only one cancellation callback, got %u\n", userdata2); - ok(group_cancel_tid == GetCurrentThreadId(), "expected tid %x, got %x\n", - GetCurrentThreadId(), group_cancel_tid); --- -2.9.0 - diff --git a/patches/ntdll-ThreadpoolCleanupGroup/0002-ntdll-Allow-to-release-threadpool-objects-while-wait.patch b/patches/ntdll-ThreadpoolCleanupGroup/0002-ntdll-Allow-to-release-threadpool-objects-while-wait.patch deleted file mode 100644 index 2f36100b..00000000 --- a/patches/ntdll-ThreadpoolCleanupGroup/0002-ntdll-Allow-to-release-threadpool-objects-while-wait.patch +++ /dev/null @@ -1,142 +0,0 @@ -From 696ecf266d29fb3120a1348a47fe55e65da2f0d6 Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Sat, 20 Aug 2016 21:22:29 +0200 -Subject: ntdll: Allow to release threadpool objects while waiting for group. - -Signed-off-by: Sebastian Lackner ---- - dlls/ntdll/threadpool.c | 51 +++++++++++++++++++++++++------------------------ - 1 file changed, 26 insertions(+), 25 deletions(-) - -diff --git a/dlls/ntdll/threadpool.c b/dlls/ntdll/threadpool.c -index 5d5b49d..eea5a88 100644 ---- a/dlls/ntdll/threadpool.c -+++ b/dlls/ntdll/threadpool.c -@@ -2,7 +2,7 @@ - * Thread pooling - * - * Copyright (c) 2006 Robert Shearman -- * Copyright (c) 2014-2015 Sebastian Lackner -+ * Copyright (c) 2014-2016 Sebastian Lackner - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public -@@ -327,7 +327,7 @@ static inline struct threadpool_instance *impl_from_TP_CALLBACK_INSTANCE( TP_CAL - - static void CALLBACK threadpool_worker_proc( void *param ); - static void tp_object_submit( struct threadpool_object *object, BOOL signaled ); --static void tp_object_shutdown( struct threadpool_object *object ); -+static void tp_object_prepare_shutdown( struct threadpool_object *object ); - static BOOL tp_object_release( struct threadpool_object *object ); - static struct threadpool *default_threadpool = NULL; - -@@ -1886,7 +1886,8 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa - - if (is_simple_callback) - { -- tp_object_shutdown( object ); -+ tp_object_prepare_shutdown( object ); -+ object->shutdown = TRUE; - tp_object_release( object ); - } - } -@@ -2001,19 +2002,16 @@ static void tp_object_wait( struct threadpool_object *object, BOOL group_wait ) - } - - /*********************************************************************** -- * tp_object_shutdown (internal) -+ * tp_object_prepare_shutdown (internal) - * -- * Marks a threadpool object for shutdown (which means that no further -- * tasks can be submitted). -+ * Prepares a threadpool object for shutdown. - */ --static void tp_object_shutdown( struct threadpool_object *object ) -+static void tp_object_prepare_shutdown( struct threadpool_object *object ) - { - if (object->type == TP_OBJECT_TYPE_TIMER) - tp_timerqueue_unlock( object ); - else if (object->type == TP_OBJECT_TYPE_WAIT) - tp_waitqueue_unlock( object ); -- -- object->shutdown = TRUE; - } - - /*********************************************************************** -@@ -2574,23 +2572,18 @@ VOID WINAPI TpReleaseCleanupGroupMembers( TP_CLEANUP_GROUP *group, BOOL cancel_p - 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) - { -- 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 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 ); -+ tp_object_prepare_shutdown( object ); - } - - /* Move members to a new temporary list */ -@@ -2612,6 +2605,11 @@ VOID WINAPI TpReleaseCleanupGroupMembers( TP_CLEANUP_GROUP *group, BOOL cancel_p - LIST_FOR_EACH_ENTRY_SAFE( object, next, &members, struct threadpool_object, group_entry ) - { - tp_object_wait( object, TRUE ); -+ -+ if (object->type != TP_OBJECT_TYPE_SIMPLE && !object->shutdown) -+ tp_object_release( object ); -+ -+ object->shutdown = TRUE; - tp_object_release( object ); - } - } -@@ -2638,7 +2636,8 @@ VOID WINAPI TpReleaseTimer( TP_TIMER *timer ) - - TRACE( "%p\n", timer ); - -- tp_object_shutdown( this ); -+ tp_object_prepare_shutdown( this ); -+ this->shutdown = TRUE; - tp_object_release( this ); - } - -@@ -2651,7 +2650,8 @@ VOID WINAPI TpReleaseWait( TP_WAIT *wait ) - - TRACE( "%p\n", wait ); - -- tp_object_shutdown( this ); -+ tp_object_prepare_shutdown( this ); -+ this->shutdown = TRUE; - tp_object_release( this ); - } - -@@ -2664,7 +2664,8 @@ VOID WINAPI TpReleaseWork( TP_WORK *work ) - - TRACE( "%p\n", work ); - -- tp_object_shutdown( this ); -+ tp_object_prepare_shutdown( this ); -+ this->shutdown = TRUE; - tp_object_release( this ); - } - --- -2.9.0 - diff --git a/patches/ntdll-ThreadpoolCleanupGroup/0003-ntdll-tests-Add-tests-for-releasing-threadpool-objec.patch b/patches/ntdll-ThreadpoolCleanupGroup/0003-ntdll-tests-Add-tests-for-releasing-threadpool-objec.patch deleted file mode 100644 index bb365f34..00000000 --- a/patches/ntdll-ThreadpoolCleanupGroup/0003-ntdll-tests-Add-tests-for-releasing-threadpool-objec.patch +++ /dev/null @@ -1,148 +0,0 @@ -From 8eb37c4da70b875e1daf4976ec8624c26a2266db Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Sat, 20 Aug 2016 21:22:54 +0200 -Subject: ntdll/tests: Add tests for releasing threadpool objects during - TpReleaseCleanupGroupMembers. - -Signed-off-by: Sebastian Lackner ---- - dlls/ntdll/tests/threadpool.c | 109 +++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 108 insertions(+), 1 deletion(-) - -diff --git a/dlls/ntdll/tests/threadpool.c b/dlls/ntdll/tests/threadpool.c -index 9b4b522..7672d63 100644 ---- a/dlls/ntdll/tests/threadpool.c -+++ b/dlls/ntdll/tests/threadpool.c -@@ -1,7 +1,7 @@ - /* - * Unit test suite for thread pool functions - * -- * Copyright 2015 Sebastian Lackner -+ * Copyright 2015-2016 Sebastian Lackner - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public -@@ -705,6 +705,112 @@ static void test_tp_work_scheduler(void) - pTpReleasePool(pool); - } - -+static void CALLBACK work_release_cb(TP_CALLBACK_INSTANCE *instance, void *userdata, TP_WORK *work) -+{ -+ HANDLE semaphore = userdata; -+ trace("Running work release callback\n"); -+ ReleaseSemaphore(semaphore, 1, NULL); -+ Sleep(200); /* wait until main thread is in TpReleaseCleanupGroupMembers */ -+ pTpReleaseWork(work); -+} -+ -+static void CALLBACK timer_release_cb(TP_CALLBACK_INSTANCE *instance, void *userdata, TP_TIMER *timer) -+{ -+ HANDLE semaphore = userdata; -+ trace("Running timer release callback\n"); -+ ReleaseSemaphore(semaphore, 1, NULL); -+ Sleep(200); /* wait until main thread is in TpReleaseCleanupGroupMembers */ -+ pTpReleaseTimer(timer); -+} -+ -+static void CALLBACK wait_release_cb(TP_CALLBACK_INSTANCE *instance, void *userdata, -+ TP_WAIT *wait, TP_WAIT_RESULT result) -+{ -+ HANDLE semaphore = userdata; -+ trace("Running wait release callback\n"); -+ ReleaseSemaphore(semaphore, 1, NULL); -+ Sleep(200); /* wait until main thread is in TpReleaseCleanupGroupMembers */ -+ pTpReleaseWait(wait); -+} -+ -+static void test_tp_group_wait(void) -+{ -+ TP_CALLBACK_ENVIRON environment; -+ TP_CLEANUP_GROUP *group; -+ LARGE_INTEGER when; -+ HANDLE semaphore; -+ NTSTATUS status; -+ TP_TIMER *timer; -+ TP_WAIT *wait; -+ TP_WORK *work; -+ TP_POOL *pool; -+ DWORD result; -+ -+ semaphore = CreateSemaphoreA(NULL, 0, 1, NULL); -+ ok(semaphore != NULL, "CreateSemaphoreA failed %u\n", GetLastError()); -+ -+ /* 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 a cleanup group */ -+ group = NULL; -+ status = pTpAllocCleanupGroup(&group); -+ ok(!status, "TpAllocCleanupGroup failed with status %x\n", status); -+ ok(group != NULL, "expected pool != NULL\n"); -+ -+ /* release work object during TpReleaseCleanupGroupMembers */ -+ work = NULL; -+ memset(&environment, 0, sizeof(environment)); -+ environment.Version = 1; -+ environment.Pool = pool; -+ environment.CleanupGroup = group; -+ status = pTpAllocWork(&work, work_release_cb, semaphore, &environment); -+ ok(!status, "TpAllocWork failed with status %x\n", status); -+ ok(work != NULL, "expected work != NULL\n"); -+ pTpPostWork(work); -+ result = WaitForSingleObject(semaphore, 1000); -+ ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); -+ pTpReleaseCleanupGroupMembers(group, FALSE, NULL); -+ -+ /* release timer object during TpReleaseCleanupGroupMembers */ -+ timer = NULL; -+ memset(&environment, 0, sizeof(environment)); -+ environment.Version = 1; -+ environment.Pool = pool; -+ environment.CleanupGroup = group; -+ status = pTpAllocTimer(&timer, timer_release_cb, semaphore, &environment); -+ ok(!status, "TpAllocTimer failed with status %x\n", status); -+ ok(timer != NULL, "expected timer != NULL\n"); -+ when.QuadPart = 0; -+ pTpSetTimer(timer, &when, 0, 0); -+ result = WaitForSingleObject(semaphore, 1000); -+ ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); -+ pTpReleaseCleanupGroupMembers(group, FALSE, NULL); -+ -+ /* release wait object during TpReleaseCleanupGroupMembers */ -+ wait = NULL; -+ memset(&environment, 0, sizeof(environment)); -+ environment.Version = 1; -+ environment.Pool = pool; -+ environment.CleanupGroup = group; -+ status = pTpAllocWait(&wait, wait_release_cb, semaphore, &environment); -+ ok(!status, "TpAllocWait failed with status %x\n", status); -+ ok(wait != NULL, "expected wait != NULL\n"); -+ when.QuadPart = 0; -+ pTpSetWait(wait, INVALID_HANDLE_VALUE, &when); -+ result = WaitForSingleObject(semaphore, 1000); -+ ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); -+ pTpReleaseCleanupGroupMembers(group, FALSE, NULL); -+ -+ /* cleanup */ -+ pTpReleaseCleanupGroup(group); -+ pTpReleasePool(pool); -+ CloseHandle(semaphore); -+} -+ - static DWORD group_cancel_tid; - - static void CALLBACK group_cancel_cb(TP_CALLBACK_INSTANCE *instance, void *userdata) -@@ -1679,6 +1785,7 @@ START_TEST(threadpool) - test_tp_simple(); - test_tp_work(); - test_tp_work_scheduler(); -+ test_tp_group_wait(); - test_tp_group_cancel(); - test_tp_instance(); - test_tp_disassociate(); --- -2.9.0 - diff --git a/patches/ntdll-ThreadpoolCleanupGroup/0004-ntdll-Call-group-cancel-callback-with-the-correct-ar.patch b/patches/ntdll-ThreadpoolCleanupGroup/0004-ntdll-Call-group-cancel-callback-with-the-correct-ar.patch deleted file mode 100644 index a09c903d..00000000 --- a/patches/ntdll-ThreadpoolCleanupGroup/0004-ntdll-Call-group-cancel-callback-with-the-correct-ar.patch +++ /dev/null @@ -1,151 +0,0 @@ -From 5ed40666bb3c8587a57e269e571f64cab27c20d4 Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Sat, 20 Aug 2016 21:23:24 +0200 -Subject: ntdll: Call group cancel callback with the correct arguments. - -Signed-off-by: Sebastian Lackner ---- - dlls/ntdll/tests/threadpool.c | 54 ++++++++++++++++++++++++++++++++++++------- - dlls/ntdll/threadpool.c | 7 +++--- - 2 files changed, 50 insertions(+), 11 deletions(-) - -diff --git a/dlls/ntdll/tests/threadpool.c b/dlls/ntdll/tests/threadpool.c -index 7672d63..f59a15c 100644 ---- a/dlls/ntdll/tests/threadpool.c -+++ b/dlls/ntdll/tests/threadpool.c -@@ -813,21 +813,25 @@ static void test_tp_group_wait(void) - - static DWORD group_cancel_tid; - --static void CALLBACK group_cancel_cb(TP_CALLBACK_INSTANCE *instance, void *userdata) -+static void CALLBACK simple_group_cancel_cb(TP_CALLBACK_INSTANCE *instance, void *userdata) - { - HANDLE *semaphores = userdata; - NTSTATUS status; - DWORD result; -+ int i; - -- trace("Running group cancel callback\n"); -+ trace("Running simple group cancel callback\n"); - - status = pTpCallbackMayRunLong(instance); - ok(status == STATUS_TOO_MANY_THREADS || broken(status == 1) /* Win Vista / 2008 */, - "expected STATUS_TOO_MANY_THREADS, got %08x\n", status); - - ReleaseSemaphore(semaphores[1], 1, NULL); -- result = WaitForSingleObject(semaphores[0], 1000); -- ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); -+ for (i = 0; i < 4; i++) -+ { -+ result = WaitForSingleObject(semaphores[0], 1000); -+ ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); -+ } - ReleaseSemaphore(semaphores[1], 1, NULL); - } - -@@ -836,6 +840,7 @@ static void CALLBACK group_cancel_cleanup_release_cb(void *object, void *userdat - HANDLE *semaphores = userdata; - trace("Running group cancel cleanup release callback\n"); - group_cancel_tid = GetCurrentThreadId(); -+ ok(object == (void *)0xdeadbeef, "expected 0xdeadbeef, got %p\n", object); - ReleaseSemaphore(semaphores[0], 1, NULL); - } - -@@ -846,7 +851,23 @@ static void CALLBACK group_cancel_cleanup_increment_cb(void *object, void *userd - InterlockedIncrement((LONG *)userdata); - } - --static void CALLBACK unexpected_cb(TP_CALLBACK_INSTANCE *instance, void *userdata) -+static void CALLBACK unexpected_simple_cb(TP_CALLBACK_INSTANCE *instance, void *userdata) -+{ -+ ok(0, "Unexpected callback\n"); -+} -+ -+static void CALLBACK unexpected_work_cb(TP_CALLBACK_INSTANCE *instance, void *userdata, TP_WORK *work) -+{ -+ ok(0, "Unexpected callback\n"); -+} -+ -+static void CALLBACK unexpected_timer_cb(TP_CALLBACK_INSTANCE *instance, void *userdata, TP_TIMER *timer) -+{ -+ ok(0, "Unexpected callback\n"); -+} -+ -+static void CALLBACK unexpected_wait_cb(TP_CALLBACK_INSTANCE *instance, void *userdata, -+ TP_WAIT *wait, TP_WAIT_RESULT result) - { - ok(0, "Unexpected callback\n"); - } -@@ -858,12 +879,14 @@ static void test_tp_group_cancel(void) - LONG userdata, userdata2; - HANDLE semaphores[2]; - NTSTATUS status; -+ TP_TIMER *timer; -+ TP_WAIT *wait; - TP_WORK *work; - TP_POOL *pool; - DWORD result; - int i; - -- semaphores[0] = CreateSemaphoreA(NULL, 0, 1, NULL); -+ semaphores[0] = CreateSemaphoreA(NULL, 0, 4, NULL); - ok(semaphores[0] != NULL, "CreateSemaphoreA failed %u\n", GetLastError()); - semaphores[1] = CreateSemaphoreA(NULL, 0, 1, NULL); - ok(semaphores[1] != NULL, "CreateSemaphoreA failed %u\n", GetLastError()); -@@ -885,7 +908,7 @@ static void test_tp_group_cancel(void) - memset(&environment, 0, sizeof(environment)); - environment.Version = 1; - environment.Pool = pool; -- status = pTpSimpleTryPost(group_cancel_cb, semaphores, &environment); -+ status = pTpSimpleTryPost(simple_group_cancel_cb, semaphores, &environment); - ok(!status, "TpSimpleTryPost failed with status %x\n", status); - result = WaitForSingleObject(semaphores[1], 1000); - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); -@@ -895,9 +918,24 @@ static void test_tp_group_cancel(void) - environment.Pool = pool; - environment.CleanupGroup = group; - environment.CleanupGroupCancelCallback = group_cancel_cleanup_release_cb; -- status = pTpSimpleTryPost(unexpected_cb, NULL, &environment); -+ status = pTpSimpleTryPost(unexpected_simple_cb, (void *)0xdeadbeef, &environment); - ok(!status, "TpSimpleTryPost failed with status %x\n", status); - -+ work = NULL; -+ status = pTpAllocWork(&work, unexpected_work_cb, (void *)0xdeadbeef, &environment); -+ ok(!status, "TpAllocWork failed with status %x\n", status); -+ ok(work != NULL, "expected work != NULL\n"); -+ -+ timer = NULL; -+ status = pTpAllocTimer(&timer, unexpected_timer_cb, (void *)0xdeadbeef, &environment); -+ ok(!status, "TpAllocTimer failed with status %x\n", status); -+ ok(timer != NULL, "expected timer != NULL\n"); -+ -+ wait = NULL; -+ status = pTpAllocWait(&wait, unexpected_wait_cb, (void *)0xdeadbeef, &environment); -+ ok(!status, "TpAllocWait failed with status %x\n", status); -+ ok(wait != NULL, "expected wait != NULL\n"); -+ - group_cancel_tid = 0xdeadbeef; - pTpReleaseCleanupGroupMembers(group, TRUE, semaphores); - result = WaitForSingleObject(semaphores[1], 1000); -diff --git a/dlls/ntdll/threadpool.c b/dlls/ntdll/threadpool.c -index eea5a88..61f6ea0 100644 ---- a/dlls/ntdll/threadpool.c -+++ b/dlls/ntdll/threadpool.c -@@ -1966,10 +1966,11 @@ static void tp_object_cancel( struct threadpool_object *object, BOOL group_cance - RtlLeaveCriticalSection( &pool->cs ); - - /* Execute group cancellation callback if defined, and if this was actually a group cancel. */ -- if (pending_callbacks && group_cancel && object->group_cancel_callback) -+ if (group_cancel && object->group_cancel_callback) - { -- TRACE( "executing group cancel callback %p(%p, %p)\n", object->group_cancel_callback, object, userdata ); -- object->group_cancel_callback( object, userdata ); -+ TRACE( "executing group cancel callback %p(%p, %p)\n", -+ object->group_cancel_callback, object->userdata, userdata ); -+ object->group_cancel_callback( object->userdata, userdata ); - TRACE( "callback %p returned\n", object->group_cancel_callback ); - } - --- -2.9.0 - diff --git a/patches/ntdll-ThreadpoolCleanupGroup/0005-ntdll-Group-cancel-callbacks-should-be-executed-afte.patch b/patches/ntdll-ThreadpoolCleanupGroup/0005-ntdll-Group-cancel-callbacks-should-be-executed-afte.patch deleted file mode 100644 index a00f82ea..00000000 --- a/patches/ntdll-ThreadpoolCleanupGroup/0005-ntdll-Group-cancel-callbacks-should-be-executed-afte.patch +++ /dev/null @@ -1,193 +0,0 @@ -From 0a7918f7b5703de00508a54baf82a6423e0a04f5 Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Sat, 20 Aug 2016 21:23:48 +0200 -Subject: ntdll: Group cancel callbacks should be executed after waiting for - pending callbacks. - -Signed-off-by: Sebastian Lackner ---- - dlls/ntdll/tests/threadpool.c | 65 +++++++++++++++++++++++++++++++++++++++++++ - dlls/ntdll/threadpool.c | 29 +++++++++---------- - 2 files changed, 80 insertions(+), 14 deletions(-) - -diff --git a/dlls/ntdll/tests/threadpool.c b/dlls/ntdll/tests/threadpool.c -index f59a15c..7eccb23 100644 ---- a/dlls/ntdll/tests/threadpool.c -+++ b/dlls/ntdll/tests/threadpool.c -@@ -835,6 +835,18 @@ static void CALLBACK simple_group_cancel_cb(TP_CALLBACK_INSTANCE *instance, void - ReleaseSemaphore(semaphores[1], 1, NULL); - } - -+static void CALLBACK work_group_cancel_cb(TP_CALLBACK_INSTANCE *instance, void *userdata, TP_WORK *work) -+{ -+ HANDLE *semaphores = userdata; -+ DWORD result; -+ -+ trace("Running work group cancel callback\n"); -+ -+ ReleaseSemaphore(semaphores[1], 1, NULL); -+ result = WaitForSingleObject(semaphores[0], 200); -+ ok(result == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", result); -+} -+ - static void CALLBACK group_cancel_cleanup_release_cb(void *object, void *userdata) - { - HANDLE *semaphores = userdata; -@@ -844,6 +856,15 @@ static void CALLBACK group_cancel_cleanup_release_cb(void *object, void *userdat - ReleaseSemaphore(semaphores[0], 1, NULL); - } - -+static void CALLBACK group_cancel_cleanup_release2_cb(void *object, void *userdata) -+{ -+ HANDLE *semaphores = userdata; -+ trace("Running group cancel cleanup release2 callback\n"); -+ group_cancel_tid = GetCurrentThreadId(); -+ ok(object == userdata, "expected %p, got %p\n", userdata, object); -+ ReleaseSemaphore(semaphores[0], 1, NULL); -+} -+ - static void CALLBACK group_cancel_cleanup_increment_cb(void *object, void *userdata) - { - trace("Running group cancel cleanup increment callback\n"); -@@ -872,6 +893,11 @@ static void CALLBACK unexpected_wait_cb(TP_CALLBACK_INSTANCE *instance, void *us - ok(0, "Unexpected callback\n"); - } - -+static void CALLBACK unexpected_group_cancel_cleanup_cb(void *object, void *userdata) -+{ -+ ok(0, "Unexpected callback\n"); -+} -+ - static void test_tp_group_cancel(void) - { - TP_CALLBACK_ENVIRON environment; -@@ -943,6 +969,45 @@ static void test_tp_group_cancel(void) - ok(group_cancel_tid == GetCurrentThreadId(), "expected tid %x, got %x\n", - GetCurrentThreadId(), group_cancel_tid); - -+ /* test if cancellation callbacks are executed before or after wait */ -+ work = NULL; -+ memset(&environment, 0, sizeof(environment)); -+ environment.Version = 1; -+ environment.Pool = pool; -+ environment.CleanupGroup = group; -+ environment.CleanupGroupCancelCallback = group_cancel_cleanup_release2_cb; -+ status = pTpAllocWork(&work, work_group_cancel_cb, semaphores, &environment); -+ ok(!status, "TpAllocWork failed with status %x\n", status); -+ ok(work != NULL, "expected work != NULL\n"); -+ pTpPostWork(work); -+ pTpPostWork(work); -+ -+ result = WaitForSingleObject(semaphores[1], 1000); -+ ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); -+ -+ group_cancel_tid = 0xdeadbeef; -+ pTpReleaseCleanupGroupMembers(group, TRUE, semaphores); -+ result = WaitForSingleObject(semaphores[0], 1000); -+ ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); -+ ok(group_cancel_tid == GetCurrentThreadId(), "expected tid %x, got %x\n", -+ GetCurrentThreadId(), group_cancel_tid); -+ -+ /* group cancel callback is not executed if object is destroyed while waiting */ -+ work = NULL; -+ memset(&environment, 0, sizeof(environment)); -+ environment.Version = 1; -+ environment.Pool = pool; -+ environment.CleanupGroup = group; -+ environment.CleanupGroupCancelCallback = unexpected_group_cancel_cleanup_cb; -+ status = pTpAllocWork(&work, work_release_cb, semaphores[1], &environment); -+ ok(!status, "TpAllocWork failed with status %x\n", status); -+ ok(work != NULL, "expected work != NULL\n"); -+ pTpPostWork(work); -+ -+ result = WaitForSingleObject(semaphores[1], 1000); -+ ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); -+ pTpReleaseCleanupGroupMembers(group, TRUE, NULL); -+ - /* test cancellation callback for objects with multiple instances */ - work = NULL; - memset(&environment, 0, sizeof(environment)); -diff --git a/dlls/ntdll/threadpool.c b/dlls/ntdll/threadpool.c -index 61f6ea0..a572869 100644 ---- a/dlls/ntdll/threadpool.c -+++ b/dlls/ntdll/threadpool.c -@@ -1948,7 +1948,7 @@ static void tp_object_submit( struct threadpool_object *object, BOOL signaled ) - * - * Cancels all currently pending callbacks for a specific object. - */ --static void tp_object_cancel( struct threadpool_object *object, BOOL group_cancel, PVOID userdata ) -+static void tp_object_cancel( struct threadpool_object *object ) - { - struct threadpool *pool = object->pool; - LONG pending_callbacks = 0; -@@ -1965,15 +1965,6 @@ static void tp_object_cancel( struct threadpool_object *object, BOOL group_cance - } - RtlLeaveCriticalSection( &pool->cs ); - -- /* Execute group cancellation callback if defined, and if this was actually a group cancel. */ -- if (group_cancel && object->group_cancel_callback) -- { -- TRACE( "executing group cancel callback %p(%p, %p)\n", -- object->group_cancel_callback, object->userdata, userdata ); -- object->group_cancel_callback( object->userdata, userdata ); -- TRACE( "callback %p returned\n", object->group_cancel_callback ); -- } -- - while (pending_callbacks--) - tp_object_release( object ); - } -@@ -2598,7 +2589,7 @@ VOID WINAPI TpReleaseCleanupGroupMembers( TP_CLEANUP_GROUP *group, BOOL cancel_p - { - LIST_FOR_EACH_ENTRY( object, &members, struct threadpool_object, group_entry ) - { -- tp_object_cancel( object, TRUE, userdata ); -+ tp_object_cancel( object ); - } - } - -@@ -2607,6 +2598,16 @@ VOID WINAPI TpReleaseCleanupGroupMembers( TP_CLEANUP_GROUP *group, BOOL cancel_p - { - tp_object_wait( object, TRUE ); - -+ /* Execute group cancellation callback if defined, and if this was actually a group cancel. */ -+ if ((object->type == TP_OBJECT_TYPE_SIMPLE || !object->shutdown) && -+ cancel_pending && object->group_cancel_callback) -+ { -+ TRACE( "executing group cancel callback %p(%p, %p)\n", -+ object->group_cancel_callback, object->userdata, userdata ); -+ object->group_cancel_callback( object->userdata, userdata ); -+ TRACE( "callback %p returned\n", object->group_cancel_callback ); -+ } -+ - if (object->type != TP_OBJECT_TYPE_SIMPLE && !object->shutdown) - tp_object_release( object ); - -@@ -2900,7 +2901,7 @@ VOID WINAPI TpWaitForTimer( TP_TIMER *timer, BOOL cancel_pending ) - TRACE( "%p %d\n", timer, cancel_pending ); - - if (cancel_pending) -- tp_object_cancel( this, FALSE, NULL ); -+ tp_object_cancel( this ); - tp_object_wait( this, FALSE ); - } - -@@ -2914,7 +2915,7 @@ VOID WINAPI TpWaitForWait( TP_WAIT *wait, BOOL cancel_pending ) - TRACE( "%p %d\n", wait, cancel_pending ); - - if (cancel_pending) -- tp_object_cancel( this, FALSE, NULL ); -+ tp_object_cancel( this ); - tp_object_wait( this, FALSE ); - } - -@@ -2928,6 +2929,6 @@ VOID WINAPI TpWaitForWork( TP_WORK *work, BOOL cancel_pending ) - TRACE( "%p %u\n", work, cancel_pending ); - - if (cancel_pending) -- tp_object_cancel( this, FALSE, NULL ); -+ tp_object_cancel( this ); - tp_object_wait( this, FALSE ); - } --- -2.9.0 - diff --git a/patches/ntdll-ThreadpoolCleanupGroup/0006-ntdll-Do-not-call-group-cancel-callback-for-finished.patch b/patches/ntdll-ThreadpoolCleanupGroup/0006-ntdll-Do-not-call-group-cancel-callback-for-finished.patch deleted file mode 100644 index caa0fbea..00000000 --- a/patches/ntdll-ThreadpoolCleanupGroup/0006-ntdll-Do-not-call-group-cancel-callback-for-finished.patch +++ /dev/null @@ -1,114 +0,0 @@ -From 0415a5cdbebd81532008f059a163cd18da2ddadb Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Sat, 20 Aug 2016 22:38:43 +0200 -Subject: ntdll: Do not call group cancel callback for finished simple - callbacks. (v2) - -Signed-off-by: Sebastian Lackner ---- - dlls/ntdll/tests/threadpool.c | 20 ++++++++++++++++++++ - dlls/ntdll/threadpool.c | 33 +++++++++++++++++++-------------- - 2 files changed, 39 insertions(+), 14 deletions(-) - -diff --git a/dlls/ntdll/tests/threadpool.c b/dlls/ntdll/tests/threadpool.c -index 7eccb23..af0b667 100644 ---- a/dlls/ntdll/tests/threadpool.c -+++ b/dlls/ntdll/tests/threadpool.c -@@ -705,6 +705,14 @@ static void test_tp_work_scheduler(void) - pTpReleasePool(pool); - } - -+static void CALLBACK simple_release_cb(TP_CALLBACK_INSTANCE *instance, void *userdata) -+{ -+ HANDLE *semaphores = userdata; -+ trace("Running simple release callback\n"); -+ ReleaseSemaphore(semaphores, 1, NULL); -+ Sleep(200); /* wait until main thread is in TpReleaseCleanupGroupMembers */ -+} -+ - static void CALLBACK work_release_cb(TP_CALLBACK_INSTANCE *instance, void *userdata, TP_WORK *work) - { - HANDLE semaphore = userdata; -@@ -1008,6 +1016,18 @@ static void test_tp_group_cancel(void) - ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); - pTpReleaseCleanupGroupMembers(group, TRUE, NULL); - -+ /* terminated simple callbacks should not trigger the group cancel callback */ -+ memset(&environment, 0, sizeof(environment)); -+ environment.Version = 1; -+ environment.Pool = pool; -+ environment.CleanupGroup = group; -+ environment.CleanupGroupCancelCallback = unexpected_group_cancel_cleanup_cb; -+ status = pTpSimpleTryPost(simple_release_cb, semaphores[1], &environment); -+ ok(!status, "TpSimpleTryPost failed with status %x\n", status); -+ result = WaitForSingleObject(semaphores[1], 1000); -+ ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result); -+ pTpReleaseCleanupGroupMembers(group, TRUE, semaphores); -+ - /* test cancellation callback for objects with multiple instances */ - work = NULL; - memset(&environment, 0, sizeof(environment)); -diff --git a/dlls/ntdll/threadpool.c b/dlls/ntdll/threadpool.c -index a572869..04790aa 100644 ---- a/dlls/ntdll/threadpool.c -+++ b/dlls/ntdll/threadpool.c -@@ -1885,11 +1885,7 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa - } - - if (is_simple_callback) -- { -- tp_object_prepare_shutdown( object ); -- object->shutdown = TRUE; - tp_object_release( object ); -- } - } - - /*********************************************************************** -@@ -2185,6 +2181,13 @@ static void CALLBACK threadpool_worker_proc( void *param ) - RtlEnterCriticalSection( &pool->cs ); - pool->num_busy_workers--; - -+ /* Simple callbacks are automatically shutdown after execution. */ -+ if (object->type == TP_OBJECT_TYPE_SIMPLE) -+ { -+ tp_object_prepare_shutdown( object ); -+ object->shutdown = TRUE; -+ } -+ - object->num_running_callbacks--; - if (!object->num_pending_callbacks && !object->num_running_callbacks) - RtlWakeAllConditionVariable( &object->group_finished_event ); -@@ -2598,18 +2601,20 @@ VOID WINAPI TpReleaseCleanupGroupMembers( TP_CLEANUP_GROUP *group, BOOL cancel_p - { - tp_object_wait( object, TRUE ); - -- /* Execute group cancellation callback if defined, and if this was actually a group cancel. */ -- if ((object->type == TP_OBJECT_TYPE_SIMPLE || !object->shutdown) && -- cancel_pending && object->group_cancel_callback) -+ if (!object->shutdown) - { -- TRACE( "executing group cancel callback %p(%p, %p)\n", -- object->group_cancel_callback, object->userdata, userdata ); -- object->group_cancel_callback( object->userdata, userdata ); -- TRACE( "callback %p returned\n", object->group_cancel_callback ); -- } -+ /* Execute group cancellation callback if defined, and if this was actually a group cancel. */ -+ if (cancel_pending && object->group_cancel_callback) -+ { -+ TRACE( "executing group cancel callback %p(%p, %p)\n", -+ object->group_cancel_callback, object->userdata, userdata ); -+ object->group_cancel_callback( object->userdata, userdata ); -+ TRACE( "callback %p returned\n", object->group_cancel_callback ); -+ } - -- if (object->type != TP_OBJECT_TYPE_SIMPLE && !object->shutdown) -- tp_object_release( object ); -+ if (object->type != TP_OBJECT_TYPE_SIMPLE) -+ tp_object_release( object ); -+ } - - object->shutdown = TRUE; - tp_object_release( object ); --- -2.9.0 - diff --git a/patches/ntdll-ThreadpoolCleanupGroup/0007-services-Remove-synchronization-for-CloseThreadpoolC.patch b/patches/ntdll-ThreadpoolCleanupGroup/0007-services-Remove-synchronization-for-CloseThreadpoolC.patch deleted file mode 100644 index 8a482b83..00000000 --- a/patches/ntdll-ThreadpoolCleanupGroup/0007-services-Remove-synchronization-for-CloseThreadpoolC.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 6746c0e13d0536a3463ac05c4c6ca5124f3ee4cd Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Sat, 20 Aug 2016 21:24:52 +0200 -Subject: services: Remove synchronization for - CloseThreadpoolCleanupGroupMembers. - -Signed-off-by: Sebastian Lackner ---- - programs/services/rpc.c | 28 ++++++++-------------------- - 1 file changed, 8 insertions(+), 20 deletions(-) - -diff --git a/programs/services/rpc.c b/programs/services/rpc.c -index 688e4a0..bd6af95 100644 ---- a/programs/services/rpc.c -+++ b/programs/services/rpc.c -@@ -85,30 +85,22 @@ struct sc_lock - struct scmdatabase *db; - }; - --static CRITICAL_SECTION shutdown_cs; --static CRITICAL_SECTION_DEBUG critsect_debug = --{ -- 0, 0, &shutdown_cs, -- { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList }, -- 0, 0, { (DWORD_PTR)(__FILE__ ": shutdown_cs") } --}; --static CRITICAL_SECTION shutdown_cs = { &critsect_debug, -1, 0, 0, 0, 0 }; --static BOOL service_shutdown; -- - static PTP_CLEANUP_GROUP cleanup_group; - HANDLE exit_event; - -+static void CALLBACK group_cancel_callback(void *object, void *userdata) -+{ -+ struct process_entry *process = object; -+ release_process(process); -+} -+ - static void CALLBACK terminate_callback(TP_CALLBACK_INSTANCE *instance, void *context, - TP_WAIT *wait, TP_WAIT_RESULT result) - { - struct process_entry *process = context; - if (result == WAIT_TIMEOUT) process_terminate(process); - release_process(process); -- -- /* synchronize with CloseThreadpoolCleanupGroupMembers */ -- EnterCriticalSection(&shutdown_cs); -- if (!service_shutdown) CloseThreadpoolWait(wait); -- LeaveCriticalSection(&shutdown_cs); -+ CloseThreadpoolWait(wait); - } - - static void terminate_after_timeout(struct process_entry *process, DWORD timeout) -@@ -121,6 +113,7 @@ static void terminate_after_timeout(struct process_entry *process, DWORD timeout - memset(&environment, 0, sizeof(environment)); - environment.Version = 1; - environment.CleanupGroup = cleanup_group; -+ environment.CleanupGroupCancelCallback = group_cancel_callback; - - timestamp.QuadPart = (ULONGLONG)timeout * -10000; - ft.dwLowDateTime = timestamp.u.LowPart; -@@ -1914,11 +1907,6 @@ void RPC_Stop(void) - RpcMgmtStopServerListening(NULL); - RpcServerUnregisterIf(svcctl_v2_0_s_ifspec, NULL, TRUE); - -- /* synchronize with CloseThreadpoolWait */ -- EnterCriticalSection(&shutdown_cs); -- service_shutdown = TRUE; -- LeaveCriticalSection(&shutdown_cs); -- - CloseThreadpoolCleanupGroupMembers(cleanup_group, TRUE, NULL); - CloseThreadpoolCleanupGroup(cleanup_group); - CloseHandle(exit_event); --- -2.9.0 - diff --git a/patches/ntdll-ThreadpoolCleanupGroup/definition b/patches/ntdll-ThreadpoolCleanupGroup/definition deleted file mode 100644 index 440601d6..00000000 --- a/patches/ntdll-ThreadpoolCleanupGroup/definition +++ /dev/null @@ -1 +0,0 @@ -Fixes: Fix multiple bugs related to threadpool cleanup groups and cancel callbacks diff --git a/patches/oleaut32-OLEPictureImpl_SaveAsFile/0001-gdiplus-Reimplement-metafile-loading-using-gdi32-ins.patch b/patches/oleaut32-OLEPictureImpl_SaveAsFile/0001-gdiplus-Reimplement-metafile-loading-using-gdi32-ins.patch deleted file mode 100644 index a8dfccf6..00000000 --- a/patches/oleaut32-OLEPictureImpl_SaveAsFile/0001-gdiplus-Reimplement-metafile-loading-using-gdi32-ins.patch +++ /dev/null @@ -1,419 +0,0 @@ -From 1da1bc40cd02cab32f45b0f043bdf37add0bac7a Mon Sep 17 00:00:00 2001 -From: Dmitry Timoshkov -Date: Mon, 21 Mar 2016 14:34:04 +0800 -Subject: gdiplus: Reimplement metafile loading using gdi32 instead of - IPicture. (v2) - ---- - dlls/gdiplus/Makefile.in | 2 +- - dlls/gdiplus/gdiplus_private.h | 1 - - dlls/gdiplus/graphics.c | 18 +--- - dlls/gdiplus/image.c | 205 +++++++++++++++++++++-------------------- - dlls/gdiplus/metafile.c | 1 - - dlls/gdiplus/tests/image.c | 10 +- - 6 files changed, 113 insertions(+), 124 deletions(-) - -diff --git a/dlls/gdiplus/Makefile.in b/dlls/gdiplus/Makefile.in -index 6495eb7..ac12bd1 100644 ---- a/dlls/gdiplus/Makefile.in -+++ b/dlls/gdiplus/Makefile.in -@@ -1,6 +1,6 @@ - MODULE = gdiplus.dll - IMPORTLIB = gdiplus --IMPORTS = uuid shlwapi oleaut32 ole32 user32 gdi32 -+IMPORTS = uuid shlwapi ole32 user32 gdi32 - DELAYIMPORTS = windowscodecs - - C_SRCS = \ -diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h -index 4ad49ca..4658fee 100644 ---- a/dlls/gdiplus/gdiplus_private.h -+++ b/dlls/gdiplus/gdiplus_private.h -@@ -333,7 +333,6 @@ struct GpAdjustableArrowCap{ - }; - - struct GpImage{ -- IPicture *picture; - IWICBitmapDecoder *decoder; - ImageType type; - GUID format; -diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c -index 370fa88..a045c61 100644 ---- a/dlls/gdiplus/graphics.c -+++ b/dlls/gdiplus/graphics.c -@@ -2904,23 +2904,7 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image - srcheight = units_to_pixels(srcheight, srcUnit, image->yres); - TRACE("src pixels: %f,%f %fx%f\n", srcx, srcy, srcwidth, srcheight); - -- if (image->picture) -- { -- if (!graphics->hdc) -- { -- FIXME("graphics object has no HDC\n"); -- } -- -- if(IPicture_Render(image->picture, graphics->hdc, -- pti[0].x, pti[0].y, pti[1].x - pti[0].x, pti[2].y - pti[0].y, -- srcx, srcy, srcwidth, srcheight, NULL) != S_OK) -- { -- if(callback) -- callback(callbackData); -- return GenericError; -- } -- } -- else if (image->type == ImageTypeBitmap) -+ if (image->type == ImageTypeBitmap) - { - GpBitmap* bitmap = (GpBitmap*)image; - BOOL do_resampling = FALSE; -diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c -index c3f6a5e..bee40b9 100644 ---- a/dlls/gdiplus/image.c -+++ b/dlls/gdiplus/image.c -@@ -1,6 +1,6 @@ - /* - * Copyright (C) 2007 Google (Evan Stade) -- * Copyright (C) 2012 Dmitry Timoshkov -+ * Copyright (C) 2012,2016 Dmitry Timoshkov - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public -@@ -124,34 +124,6 @@ static ColorPalette *get_palette(IWICBitmapFrameDecode *frame, WICBitmapPaletteT - return palette; - } - --static INT ipicture_pixel_height(IPicture *pic) --{ -- HDC hdcref; -- OLE_YSIZE_HIMETRIC y; -- -- IPicture_get_Height(pic, &y); -- -- hdcref = CreateCompatibleDC(0); -- y = MulDiv(y, GetDeviceCaps(hdcref, LOGPIXELSY), INCH_HIMETRIC); -- DeleteDC(hdcref); -- -- return y; --} -- --static INT ipicture_pixel_width(IPicture *pic) --{ -- HDC hdcref; -- OLE_XSIZE_HIMETRIC x; -- -- IPicture_get_Width(pic, &x); -- -- hdcref = CreateCompatibleDC(0); -- x = MulDiv(x, GetDeviceCaps(hdcref, LOGPIXELSX), INCH_HIMETRIC); -- DeleteDC(hdcref); -- -- return x; --} -- - GpStatus WINGDIPAPI GdipBitmapApplyEffect(GpBitmap* bitmap, CGpEffect* effect, - RECT* roi, BOOL useAuxData, VOID** auxData, INT* auxDataSize) - { -@@ -1309,45 +1281,12 @@ GpStatus WINGDIPAPI GdipCloneBitmapAreaI(INT x, INT y, INT width, INT height, - - GpStatus WINGDIPAPI GdipCloneImage(GpImage *image, GpImage **cloneImage) - { -- GpStatus stat = GenericError; -- - TRACE("%p, %p\n", image, cloneImage); - - if (!image || !cloneImage) - return InvalidParameter; - -- if (image->picture) -- { -- IStream* stream; -- HRESULT hr; -- INT size; -- LARGE_INTEGER move; -- -- hr = CreateStreamOnHGlobal(0, TRUE, &stream); -- if (FAILED(hr)) -- return GenericError; -- -- hr = IPicture_SaveAsFile(image->picture, stream, FALSE, &size); -- if(FAILED(hr)) -- { -- WARN("Failed to save image on stream\n"); -- goto out; -- } -- -- /* Set seek pointer back to the beginning of the picture */ -- move.QuadPart = 0; -- hr = IStream_Seek(stream, move, STREAM_SEEK_SET, NULL); -- if (FAILED(hr)) -- goto out; -- -- stat = GdipLoadImageFromStream(stream, cloneImage); -- if (stat != Ok) WARN("Failed to load image from stream\n"); -- -- out: -- IStream_Release(stream); -- return stat; -- } -- else if (image->type == ImageTypeBitmap) -+ if (image->type == ImageTypeBitmap) - { - GpBitmap *bitmap = (GpBitmap *)image; - -@@ -1884,7 +1823,6 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromScan0(INT width, INT height, INT stride, - (*bitmap)->width = width; - (*bitmap)->height = height; - (*bitmap)->format = format; -- (*bitmap)->image.picture = NULL; - (*bitmap)->image.decoder = NULL; - (*bitmap)->hbitmap = hbitmap; - (*bitmap)->hdc = NULL; -@@ -2152,8 +2090,6 @@ static GpStatus free_image_data(GpImage *image) - WARN("invalid image: %p\n", image); - return ObjectBusy; - } -- if (image->picture) -- IPicture_Release(image->picture); - if (image->decoder) - IWICBitmapDecoder_Release(image->decoder); - heap_free(image->palette); -@@ -2219,12 +2155,6 @@ GpStatus WINGDIPAPI GdipGetImageBounds(GpImage *image, GpRectF *srcRect, - srcRect->Height = (REAL) ((GpBitmap*)image)->height; - *srcUnit = UnitPixel; - } -- else{ -- srcRect->X = srcRect->Y = 0.0; -- srcRect->Width = ipicture_pixel_width(image->picture); -- srcRect->Height = ipicture_pixel_height(image->picture); -- *srcUnit = UnitPixel; -- } - - TRACE("returning (%f, %f) (%f, %f) unit type %d\n", srcRect->X, srcRect->Y, - srcRect->Width, srcRect->Height, *srcUnit); -@@ -2248,10 +2178,6 @@ GpStatus WINGDIPAPI GdipGetImageDimension(GpImage *image, REAL *width, - *height = ((GpBitmap*)image)->height; - *width = ((GpBitmap*)image)->width; - } -- else{ -- *height = ipicture_pixel_height(image->picture); -- *width = ipicture_pixel_width(image->picture); -- } - - TRACE("returning (%f, %f)\n", *height, *width); - return Ok; -@@ -2306,8 +2232,6 @@ GpStatus WINGDIPAPI GdipGetImageHeight(GpImage *image, UINT *height) - *height = units_to_pixels(((GpMetafile*)image)->bounds.Height, ((GpMetafile*)image)->unit, image->yres); - else if(image->type == ImageTypeBitmap) - *height = ((GpBitmap*)image)->height; -- else -- *height = ipicture_pixel_height(image->picture); - - TRACE("returning %d\n", *height); - -@@ -2406,8 +2330,6 @@ GpStatus WINGDIPAPI GdipGetImageWidth(GpImage *image, UINT *width) - *width = units_to_pixels(((GpMetafile*)image)->bounds.Width, ((GpMetafile*)image)->unit, image->xres); - else if(image->type == ImageTypeBitmap) - *width = ((GpBitmap*)image)->width; -- else -- *width = ipicture_pixel_width(image->picture); - - TRACE("returning %d\n", *width); - -@@ -4037,33 +3959,118 @@ static GpStatus decode_image_tiff(IStream* stream, GpImage **image) - return decode_image_wic(stream, &GUID_ContainerFormatTiff, NULL, image); - } - --static GpStatus decode_image_olepicture_metafile(IStream* stream, GpImage **image) -+static GpStatus load_wmf(IStream *stream, GpMetafile **metafile) -+{ -+ GpStatus status = GenericError; -+ HRESULT hr; -+ UINT size; -+ LARGE_INTEGER pos; -+ WmfPlaceableFileHeader pfh; -+ BOOL is_placeable = FALSE; -+ METAHEADER mh; -+ HMETAFILE hmf; -+ void *buf; -+ -+ pos.QuadPart = 0; -+ IStream_Seek(stream, pos, STREAM_SEEK_SET, NULL); -+ -+ hr = IStream_Read(stream, &mh, sizeof(mh), &size); -+ if (hr != S_OK || size != sizeof(mh)) -+ return GenericError; -+ -+ if (mh.mtType == 0xcdd7 && mh.mtHeaderSize == 0x9ac6) -+ { -+ is_placeable = TRUE; -+ -+ pos.QuadPart = 0; -+ IStream_Seek(stream, pos, STREAM_SEEK_SET, NULL); -+ -+ hr = IStream_Read(stream, &pfh, sizeof(pfh), &size); -+ if (hr != S_OK || size != sizeof(pfh)) -+ return GenericError; -+ -+ hr = IStream_Read(stream, &mh, sizeof(mh), &size); -+ if (hr != S_OK || size != sizeof(mh)) -+ return GenericError; -+ } -+ -+ pos.QuadPart = is_placeable ? sizeof(pfh) : 0; -+ IStream_Seek(stream, pos, STREAM_SEEK_SET, NULL); -+ -+ buf = heap_alloc(mh.mtSize * 2); -+ if (!buf) return OutOfMemory; -+ -+ hr = IStream_Read(stream, buf, mh.mtSize * 2, &size); -+ if (hr == S_OK && size == mh.mtSize * 2) -+ { -+ hmf = SetMetaFileBitsEx(mh.mtSize * 2, buf); -+ if (hmf) -+ { -+ status = GdipCreateMetafileFromWmf(hmf, TRUE, is_placeable ? &pfh : NULL, metafile); -+ if (status != Ok) -+ DeleteMetaFile(hmf); -+ } -+ } -+ -+ heap_free(buf); -+ return status; -+} -+ -+static GpStatus load_emf(IStream *stream, GpMetafile **metafile) - { -- IPicture *pic; -+ GpStatus status = GenericError; -+ HRESULT hr; -+ UINT size; -+ LARGE_INTEGER pos; -+ ENHMETAHEADER emh; -+ HENHMETAFILE hemf; -+ void *buf; -+ -+ pos.QuadPart = 0; -+ IStream_Seek(stream, pos, STREAM_SEEK_SET, NULL); -+ -+ hr = IStream_Read(stream, &emh, sizeof(emh), &size); -+ if (hr != S_OK || size != sizeof(emh) || emh.dSignature != ENHMETA_SIGNATURE) -+ return GenericError; -+ -+ pos.QuadPart = 0; -+ IStream_Seek(stream, pos, STREAM_SEEK_SET, NULL); -+ -+ buf = heap_alloc(emh.nBytes); -+ if (!buf) return OutOfMemory; -+ -+ hr = IStream_Read(stream, buf, emh.nBytes, &size); -+ if (hr == S_OK && size == emh.nBytes) -+ { -+ hemf = SetEnhMetaFileBits(emh.nBytes, buf); -+ if (hemf) -+ { -+ status = GdipCreateMetafileFromEmf(hemf, FALSE, metafile); -+ if (status != Ok) -+ DeleteEnhMetaFile(hemf); -+ } -+ } -+ -+ heap_free(buf); -+ return status; -+} -+ -+static GpStatus decode_image_metafile(IStream *stream, GpImage **image) -+{ -+ GpMetafile *metafile; - - TRACE("%p %p\n", stream, image); - - if(!stream || !image) - return InvalidParameter; - -- if(OleLoadPicture(stream, 0, FALSE, &IID_IPicture, -- (LPVOID*) &pic) != S_OK){ -- TRACE("Could not load picture\n"); -+ if (load_emf(stream, &metafile) != Ok && load_wmf(stream, &metafile) != Ok) -+ { -+ TRACE("Could not load metafile\n"); - return GenericError; - } - -- /* FIXME: missing initialization code */ -- *image = heap_alloc_zero(sizeof(GpMetafile)); -- if(!*image) return OutOfMemory; -- (*image)->type = ImageTypeMetafile; -- (*image)->decoder = NULL; -- (*image)->picture = pic; -- (*image)->flags = ImageFlagsNone; -- (*image)->frame_count = 1; -- (*image)->current_frame = 0; -- (*image)->palette = NULL; -- list_init(&(*(GpMetafile**)image)->containers); -- -+ *image = (GpImage *)metafile; - TRACE("<-- %p\n", *image); - - return Ok; -@@ -4721,7 +4728,7 @@ static const struct image_codec codecs[NUM_CODECS] = { - /* SigMask */ emf_sig_mask, - }, - NULL, -- decode_image_olepicture_metafile, -+ decode_image_metafile, - NULL - }, - { -@@ -4741,7 +4748,7 @@ static const struct image_codec codecs[NUM_CODECS] = { - /* SigMask */ wmf_sig_mask, - }, - NULL, -- decode_image_olepicture_metafile, -+ decode_image_metafile, - NULL - }, - { -diff --git a/dlls/gdiplus/metafile.c b/dlls/gdiplus/metafile.c -index a854e55..8b93e81 100644 ---- a/dlls/gdiplus/metafile.c -+++ b/dlls/gdiplus/metafile.c -@@ -317,7 +317,6 @@ GpStatus WINGDIPAPI GdipRecordMetafile(HDC hdc, EmfType type, GDIPCONST GpRectF - } - - (*metafile)->image.type = ImageTypeMetafile; -- (*metafile)->image.picture = NULL; - (*metafile)->image.flags = ImageFlagsNone; - (*metafile)->image.palette = NULL; - (*metafile)->image.xres = dpix; -diff --git a/dlls/gdiplus/tests/image.c b/dlls/gdiplus/tests/image.c -index ad84feb..cabd2fce 100644 ---- a/dlls/gdiplus/tests/image.c -+++ b/dlls/gdiplus/tests/image.c -@@ -1446,19 +1446,19 @@ static void test_loadwmf(void) - - stat = GdipGetImageBounds(img, &bounds, &unit); - expect(Ok, stat); -- todo_wine expect(UnitPixel, unit); -+ expect(UnitPixel, unit); - expectf(0.0, bounds.X); - expectf(0.0, bounds.Y); -- todo_wine expectf(320.0, bounds.Width); -- todo_wine expectf(320.0, bounds.Height); -+ expectf(320.0, bounds.Width); -+ expectf(320.0, bounds.Height); - - stat = GdipGetImageHorizontalResolution(img, &res); - expect(Ok, stat); -- todo_wine expectf(1440.0, res); -+ expectf(1440.0, res); - - stat = GdipGetImageVerticalResolution(img, &res); - expect(Ok, stat); -- todo_wine expectf(1440.0, res); -+ expectf(1440.0, res); - - memset(&header, 0, sizeof(header)); - stat = GdipGetMetafileHeaderFromMetafile((GpMetafile*)img, &header); --- -2.9.0 - diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 8360d95c..756c017b 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -52,13 +52,13 @@ usage() # Get the upstream commit sha upstream_commit() { - echo "a83d5d3b83042d2305de0595c0d03e4e7bf1e29e" + echo "90173ce448e5afe55627c2cbece28fb4f6bae99d" } # Show version information version() { - echo "Wine Staging 1.9.17" + echo "Wine Staging 1.9.18 (unreleased)" echo "Copyright (C) 2014-2016 the Wine Staging project authors." echo "" echo "Patchset to be applied on upstream Wine:" @@ -238,7 +238,6 @@ patch_enable_all () enable_ntdll_SystemRoot_Symlink="$1" enable_ntdll_ThreadTime="$1" enable_ntdll_Threading="$1" - enable_ntdll_ThreadpoolCleanupGroup="$1" enable_ntdll_User_Shared_Data="$1" enable_ntdll_WRITECOPY="$1" enable_ntdll_Wait_User_APC="$1" @@ -888,9 +887,6 @@ patch_enable () ntdll-Threading) enable_ntdll_Threading="$2" ;; - ntdll-ThreadpoolCleanupGroup) - enable_ntdll_ThreadpoolCleanupGroup="$2" - ;; ntdll-User_Shared_Data) enable_ntdll_User_Shared_Data="$2" ;; @@ -2095,6 +2091,13 @@ if test "$enable_server_Stored_ACLs" -eq 1; then enable_server_File_Permissions=1 fi +if test "$enable_oleaut32_OLEPictureImpl_SaveAsFile" -eq 1; then + if test "$enable_oleaut32_Load_Save_EMF" -gt 1; then + abort "Patchset oleaut32-Load_Save_EMF disabled, but oleaut32-OLEPictureImpl_SaveAsFile depends on that." + fi + enable_oleaut32_Load_Save_EMF=1 +fi + if test "$enable_nvencodeapi_Video_Encoder" -eq 1; then if test "$enable_nvcuvid_CUDA_Video_Support" -gt 1; then abort "Patchset nvcuvid-CUDA_Video_Support disabled, but nvencodeapi-Video_Encoder depends on that." @@ -2234,20 +2237,6 @@ if test "$enable_imagehlp_ImageLoad" -eq 1; then enable_imagehlp_Cleanup=1 fi -if test "$enable_gdiplus_GdipCreateMetafileFromStream" -eq 1; then - if test "$enable_oleaut32_OLEPictureImpl_SaveAsFile" -gt 1; then - abort "Patchset oleaut32-OLEPictureImpl_SaveAsFile disabled, but gdiplus-GdipCreateMetafileFromStream depends on that." - fi - enable_oleaut32_OLEPictureImpl_SaveAsFile=1 -fi - -if test "$enable_oleaut32_OLEPictureImpl_SaveAsFile" -eq 1; then - if test "$enable_oleaut32_Load_Save_EMF" -gt 1; then - abort "Patchset oleaut32-Load_Save_EMF disabled, but oleaut32-OLEPictureImpl_SaveAsFile depends on that." - fi - enable_oleaut32_Load_Save_EMF=1 -fi - if test "$enable_dxva2_Video_Decoder" -eq 1; then if test "$enable_winecfg_Staging" -gt 1; then abort "Patchset winecfg-Staging disabled, but dxva2-Video_Decoder depends on that." @@ -3716,51 +3705,8 @@ if test "$enable_gdi32_Symbol_Truetype_Font" -eq 1; then ) >> "$patchlist" fi -# Patchset oleaut32-Load_Save_EMF -# | -# | This patchset fixes the following Wine bugs: -# | * [#40523] Implement support for loading and saving EMF to IPicture interface -# | -# | Modified files: -# | * dlls/oleaut32/olepicture.c, dlls/oleaut32/tests/olepicture.c -# | -if test "$enable_oleaut32_Load_Save_EMF" -eq 1; then - patch_apply oleaut32-Load_Save_EMF/0001-oleaut32-tests-Add-some-tests-for-loading-and-saving.patch - patch_apply oleaut32-Load_Save_EMF/0002-oleaut32-Add-support-for-loading-and-saving-EMF-to-I.patch - ( - echo '+ { "Dmitry Timoshkov", "oleaut32/tests: Add some tests for loading and saving EMF using IPicture interface.", 1 },'; - echo '+ { "Dmitry Timoshkov", "oleaut32: Add support for loading and saving EMF to IPicture interface.", 1 },'; - ) >> "$patchlist" -fi - -# Patchset oleaut32-OLEPictureImpl_SaveAsFile -# | -# | This patchset has the following (direct or indirect) dependencies: -# | * oleaut32-Load_Save_EMF -# | -# | This patchset fixes the following Wine bugs: -# | * [#8532] Implement a better stub for IPicture::SaveAsFile -# | -# | Modified files: -# | * dlls/gdiplus/Makefile.in, dlls/gdiplus/gdiplus_private.h, dlls/gdiplus/graphics.c, dlls/gdiplus/image.c, -# | dlls/gdiplus/metafile.c, dlls/gdiplus/tests/image.c, dlls/oleaut32/olepicture.c, dlls/oleaut32/tests/olepicture.c -# | -if test "$enable_oleaut32_OLEPictureImpl_SaveAsFile" -eq 1; then - patch_apply oleaut32-OLEPictureImpl_SaveAsFile/0001-gdiplus-Reimplement-metafile-loading-using-gdi32-ins.patch - patch_apply oleaut32-OLEPictureImpl_SaveAsFile/0002-oleaut32-Implement-a-better-stub-for-IPicture-SaveAs.patch - patch_apply oleaut32-OLEPictureImpl_SaveAsFile/0003-oleaut32-Implement-SaveAsFile-for-PICTYPE_ENHMETAFIL.patch - ( - echo '+ { "Dmitry Timoshkov", "gdiplus: Reimplement metafile loading using gdi32 instead of IPicture.", 2 },'; - echo '+ { "Dmitry Timoshkov", "oleaut32: Implement a better stub for IPicture::SaveAsFile.", 1 },'; - echo '+ { "Sebastian Lackner", "oleaut32: Implement SaveAsFile for PICTYPE_ENHMETAFILE.", 1 },'; - ) >> "$patchlist" -fi - # Patchset gdiplus-GdipCreateMetafileFromStream # | -# | This patchset has the following (direct or indirect) dependencies: -# | * oleaut32-Load_Save_EMF, oleaut32-OLEPictureImpl_SaveAsFile -# | # | This patchset fixes the following Wine bugs: # | * [#40325] Implement GdipCreateMetafileFromStream # | * [#27415] Implement GdipGetMetafileHeaderFromMetafile @@ -5230,30 +5176,6 @@ if test "$enable_ntdll_Threading" -eq 1; then ) >> "$patchlist" fi -# Patchset ntdll-ThreadpoolCleanupGroup -# | -# | Modified files: -# | * dlls/ntdll/tests/threadpool.c, dlls/ntdll/threadpool.c, programs/services/rpc.c -# | -if test "$enable_ntdll_ThreadpoolCleanupGroup" -eq 1; then - patch_apply ntdll-ThreadpoolCleanupGroup/0001-ntdll-tests-Use-longer-waits-to-reduce-risk-of-rando.patch - patch_apply ntdll-ThreadpoolCleanupGroup/0002-ntdll-Allow-to-release-threadpool-objects-while-wait.patch - patch_apply ntdll-ThreadpoolCleanupGroup/0003-ntdll-tests-Add-tests-for-releasing-threadpool-objec.patch - patch_apply ntdll-ThreadpoolCleanupGroup/0004-ntdll-Call-group-cancel-callback-with-the-correct-ar.patch - patch_apply ntdll-ThreadpoolCleanupGroup/0005-ntdll-Group-cancel-callbacks-should-be-executed-afte.patch - patch_apply ntdll-ThreadpoolCleanupGroup/0006-ntdll-Do-not-call-group-cancel-callback-for-finished.patch - patch_apply ntdll-ThreadpoolCleanupGroup/0007-services-Remove-synchronization-for-CloseThreadpoolC.patch - ( - echo '+ { "Sebastian Lackner", "ntdll/tests: Use longer waits to reduce risk of random failures on the testbot.", 1 },'; - echo '+ { "Sebastian Lackner", "ntdll: Allow to release threadpool objects while waiting for group.", 1 },'; - echo '+ { "Sebastian Lackner", "ntdll/tests: Add tests for releasing threadpool objects during TpReleaseCleanupGroupMembers.", 1 },'; - echo '+ { "Sebastian Lackner", "ntdll: Call group cancel callback with the correct arguments.", 1 },'; - echo '+ { "Sebastian Lackner", "ntdll: Group cancel callbacks should be executed after waiting for pending callbacks.", 1 },'; - echo '+ { "Sebastian Lackner", "ntdll: Do not call group cancel callback for finished simple callbacks.", 2 },'; - echo '+ { "Sebastian Lackner", "services: Remove synchronization for CloseThreadpoolCleanupGroupMembers.", 1 },'; - ) >> "$patchlist" -fi - # Patchset ntdll-User_Shared_Data # | # | Modified files: @@ -5594,6 +5516,43 @@ if test "$enable_oleaut32_CreateTypeLib" -eq 1; then ) >> "$patchlist" fi +# Patchset oleaut32-Load_Save_EMF +# | +# | This patchset fixes the following Wine bugs: +# | * [#40523] Implement support for loading and saving EMF to IPicture interface +# | +# | Modified files: +# | * dlls/oleaut32/olepicture.c, dlls/oleaut32/tests/olepicture.c +# | +if test "$enable_oleaut32_Load_Save_EMF" -eq 1; then + patch_apply oleaut32-Load_Save_EMF/0001-oleaut32-tests-Add-some-tests-for-loading-and-saving.patch + patch_apply oleaut32-Load_Save_EMF/0002-oleaut32-Add-support-for-loading-and-saving-EMF-to-I.patch + ( + echo '+ { "Dmitry Timoshkov", "oleaut32/tests: Add some tests for loading and saving EMF using IPicture interface.", 1 },'; + echo '+ { "Dmitry Timoshkov", "oleaut32: Add support for loading and saving EMF to IPicture interface.", 1 },'; + ) >> "$patchlist" +fi + +# Patchset oleaut32-OLEPictureImpl_SaveAsFile +# | +# | This patchset has the following (direct or indirect) dependencies: +# | * oleaut32-Load_Save_EMF +# | +# | This patchset fixes the following Wine bugs: +# | * [#8532] Implement a better stub for IPicture::SaveAsFile +# | +# | Modified files: +# | * dlls/oleaut32/olepicture.c, dlls/oleaut32/tests/olepicture.c +# | +if test "$enable_oleaut32_OLEPictureImpl_SaveAsFile" -eq 1; then + patch_apply oleaut32-OLEPictureImpl_SaveAsFile/0002-oleaut32-Implement-a-better-stub-for-IPicture-SaveAs.patch + patch_apply oleaut32-OLEPictureImpl_SaveAsFile/0003-oleaut32-Implement-SaveAsFile-for-PICTYPE_ENHMETAFIL.patch + ( + echo '+ { "Dmitry Timoshkov", "oleaut32: Implement a better stub for IPicture::SaveAsFile.", 1 },'; + echo '+ { "Sebastian Lackner", "oleaut32: Implement SaveAsFile for PICTYPE_ENHMETAFILE.", 1 },'; + ) >> "$patchlist" +fi + # Patchset oleaut32-OleLoadPicture # | # | This patchset fixes the following Wine bugs: diff --git a/staging/VERSION b/staging/VERSION index c567b0c8..9fd61484 100644 --- a/staging/VERSION +++ b/staging/VERSION @@ -1 +1 @@ -Wine Staging 1.9.17 +Wine Staging 1.9.18 (unreleased)