From 4c4c893c3025f8760a0a69ff4beea8c7d41ecec3 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Fri, 14 Feb 2020 13:01:09 +0300 Subject: [PATCH] rtworkq: Initialize MTA on startup. Signed-off-by: Nikolay Sivov Signed-off-by: Alexandre Julliard --- configure | 1 + configure.ac | 1 + dlls/rtworkq/Makefile.in | 1 + dlls/rtworkq/queue.c | 9 +++ dlls/rtworkq/tests/Makefile.in | 5 ++ dlls/rtworkq/tests/rtworkq.c | 107 +++++++++++++++++++++++++++++++++ 6 files changed, 124 insertions(+) create mode 100644 dlls/rtworkq/tests/Makefile.in create mode 100644 dlls/rtworkq/tests/rtworkq.c diff --git a/configure b/configure index cb85fb8b8fa..1d20d141c19 100755 --- a/configure +++ b/configure @@ -20864,6 +20864,7 @@ wine_fn_config_makefile dlls/rsaenh/tests enable_tests wine_fn_config_makefile dlls/rstrtmgr enable_rstrtmgr wine_fn_config_makefile dlls/rtutils enable_rtutils wine_fn_config_makefile dlls/rtworkq enable_rtworkq +wine_fn_config_makefile dlls/rtworkq/tests enable_tests wine_fn_config_makefile dlls/samlib enable_samlib wine_fn_config_makefile dlls/sane.ds enable_sane_ds wine_fn_config_makefile dlls/sapi enable_sapi diff --git a/configure.ac b/configure.ac index b3389b796bd..2e102990b5d 100644 --- a/configure.ac +++ b/configure.ac @@ -3609,6 +3609,7 @@ WINE_CONFIG_MAKEFILE(dlls/rsaenh/tests) WINE_CONFIG_MAKEFILE(dlls/rstrtmgr) WINE_CONFIG_MAKEFILE(dlls/rtutils) WINE_CONFIG_MAKEFILE(dlls/rtworkq) +WINE_CONFIG_MAKEFILE(dlls/rtworkq/tests) WINE_CONFIG_MAKEFILE(dlls/samlib) WINE_CONFIG_MAKEFILE(dlls/sane.ds) WINE_CONFIG_MAKEFILE(dlls/sapi) diff --git a/dlls/rtworkq/Makefile.in b/dlls/rtworkq/Makefile.in index a224198986a..345fad1c1e2 100644 --- a/dlls/rtworkq/Makefile.in +++ b/dlls/rtworkq/Makefile.in @@ -1,5 +1,6 @@ MODULE = rtworkq.dll IMPORTLIB = rtworkq +IMPORTS = ole32 EXTRADLLFLAGS = -mno-cygwin diff --git a/dlls/rtworkq/queue.c b/dlls/rtworkq/queue.c index 65007602c74..70af6a76584 100644 --- a/dlls/rtworkq/queue.c +++ b/dlls/rtworkq/queue.c @@ -69,6 +69,7 @@ static CRITICAL_SECTION_DEBUG queues_critsect_debug = static CRITICAL_SECTION queues_section = { &queues_critsect_debug, -1, 0, 0, 0, 0 }; static LONG platform_lock; +static CO_MTA_USAGE_COOKIE mta_cookie; static struct queue_handle *get_queue_obj(DWORD handle) { @@ -1117,6 +1118,7 @@ HRESULT WINAPI RtwqUnlockPlatform(void) static void init_system_queues(void) { struct queue_desc desc; + HRESULT hr; /* Always initialize standard queue, keep the rest lazy. */ @@ -1128,6 +1130,9 @@ static void init_system_queues(void) return; } + if (FAILED(hr = CoIncrementMTAUsage(&mta_cookie))) + WARN("Failed to initialize MTA, hr %#x.\n", hr); + desc.queue_type = RTWQ_STANDARD_WORKQUEUE; desc.ops = &pool_queue_ops; desc.target_queue = 0; @@ -1149,6 +1154,7 @@ HRESULT WINAPI RtwqStartup(void) static void shutdown_system_queues(void) { unsigned int i; + HRESULT hr; EnterCriticalSection(&queues_section); @@ -1157,6 +1163,9 @@ static void shutdown_system_queues(void) shutdown_queue(&system_queues[i]); } + if (FAILED(hr = CoDecrementMTAUsage(mta_cookie))) + WARN("Failed to uninitialize MTA, hr %#x.\n", hr); + LeaveCriticalSection(&queues_section); } diff --git a/dlls/rtworkq/tests/Makefile.in b/dlls/rtworkq/tests/Makefile.in new file mode 100644 index 00000000000..8354cd810d1 --- /dev/null +++ b/dlls/rtworkq/tests/Makefile.in @@ -0,0 +1,5 @@ +TESTDLL = rtworkq.dll +IMPORTS = rtworkq ole32 + +C_SRCS = \ + rtworkq.c diff --git a/dlls/rtworkq/tests/rtworkq.c b/dlls/rtworkq/tests/rtworkq.c new file mode 100644 index 00000000000..627e024d761 --- /dev/null +++ b/dlls/rtworkq/tests/rtworkq.c @@ -0,0 +1,107 @@ +/* + * Copyright 2020 Nikolay Sivov for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include + +#include "windef.h" +#include "winbase.h" +#include "rtworkq.h" + +#include "wine/test.h" + +static void test_platform_init(void) +{ + APTTYPEQUALIFIER qualifier; + APTTYPE apttype; + HRESULT hr; + + /* Startup initializes MTA. */ + hr = CoGetApartmentType(&apttype, &qualifier); + ok(hr == CO_E_NOTINITIALIZED, "Unexpected hr %#x.\n", hr); + + hr = RtwqStartup(); + ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr); + + hr = CoGetApartmentType(&apttype, &qualifier); + ok(hr == S_OK || broken(FAILED(hr)) /* Win8 */, "Unexpected hr %#x.\n", hr); + if (SUCCEEDED(hr)) + ok(apttype == APTTYPE_MTA && qualifier == APTTYPEQUALIFIER_IMPLICIT_MTA, + "Unexpected apartment type %d, qualifier %d.\n", apttype, qualifier); + + hr = RtwqShutdown(); + ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr); + + hr = CoGetApartmentType(&apttype, &qualifier); + ok(hr == CO_E_NOTINITIALIZED, "Unexpected hr %#x.\n", hr); + + /* Try with STA initialized before startup. */ + hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + ok(hr == S_OK, "Failed to initialize, hr %#x.\n", hr); + + hr = CoGetApartmentType(&apttype, &qualifier); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(apttype == APTTYPE_MAINSTA && qualifier == APTTYPEQUALIFIER_NONE, + "Unexpected apartment type %d, qualifier %d.\n", apttype, qualifier); + + hr = RtwqStartup(); + ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr); + + hr = CoGetApartmentType(&apttype, &qualifier); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(apttype == APTTYPE_MAINSTA && qualifier == APTTYPEQUALIFIER_NONE, + "Unexpected apartment type %d, qualifier %d.\n", apttype, qualifier); + + hr = RtwqShutdown(); + ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr); + + CoUninitialize(); + + /* Startup -> init main STA -> uninitialize -> shutdown */ + hr = RtwqStartup(); + ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr); + + hr = CoGetApartmentType(&apttype, &qualifier); + ok(hr == S_OK || broken(FAILED(hr)) /* Win8 */, "Unexpected hr %#x.\n", hr); + if (SUCCEEDED(hr)) + ok(apttype == APTTYPE_MTA && qualifier == APTTYPEQUALIFIER_IMPLICIT_MTA, + "Unexpected apartment type %d, qualifier %d.\n", apttype, qualifier); + + hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + ok(hr == S_OK, "Failed to initialize, hr %#x.\n", hr); + + hr = CoGetApartmentType(&apttype, &qualifier); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(apttype == APTTYPE_MAINSTA && qualifier == APTTYPEQUALIFIER_NONE, + "Unexpected apartment type %d, qualifier %d.\n", apttype, qualifier); + + CoUninitialize(); + + hr = CoGetApartmentType(&apttype, &qualifier); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(apttype == APTTYPE_MTA && qualifier == APTTYPEQUALIFIER_IMPLICIT_MTA, + "Unexpected apartment type %d, qualifier %d.\n", apttype, qualifier); + + hr = RtwqShutdown(); + ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr); +} + +START_TEST(rtworkq) +{ + test_platform_init(); +}