rtworkq: Initialize MTA on startup.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2020-02-14 13:01:09 +03:00 committed by Alexandre Julliard
parent 90a6c9bd53
commit 4c4c893c30
6 changed files with 124 additions and 0 deletions

1
configure vendored
View File

@ -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/rstrtmgr enable_rstrtmgr
wine_fn_config_makefile dlls/rtutils enable_rtutils wine_fn_config_makefile dlls/rtutils enable_rtutils
wine_fn_config_makefile dlls/rtworkq enable_rtworkq 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/samlib enable_samlib
wine_fn_config_makefile dlls/sane.ds enable_sane_ds wine_fn_config_makefile dlls/sane.ds enable_sane_ds
wine_fn_config_makefile dlls/sapi enable_sapi wine_fn_config_makefile dlls/sapi enable_sapi

View File

@ -3609,6 +3609,7 @@ WINE_CONFIG_MAKEFILE(dlls/rsaenh/tests)
WINE_CONFIG_MAKEFILE(dlls/rstrtmgr) WINE_CONFIG_MAKEFILE(dlls/rstrtmgr)
WINE_CONFIG_MAKEFILE(dlls/rtutils) WINE_CONFIG_MAKEFILE(dlls/rtutils)
WINE_CONFIG_MAKEFILE(dlls/rtworkq) WINE_CONFIG_MAKEFILE(dlls/rtworkq)
WINE_CONFIG_MAKEFILE(dlls/rtworkq/tests)
WINE_CONFIG_MAKEFILE(dlls/samlib) WINE_CONFIG_MAKEFILE(dlls/samlib)
WINE_CONFIG_MAKEFILE(dlls/sane.ds) WINE_CONFIG_MAKEFILE(dlls/sane.ds)
WINE_CONFIG_MAKEFILE(dlls/sapi) WINE_CONFIG_MAKEFILE(dlls/sapi)

View File

@ -1,5 +1,6 @@
MODULE = rtworkq.dll MODULE = rtworkq.dll
IMPORTLIB = rtworkq IMPORTLIB = rtworkq
IMPORTS = ole32
EXTRADLLFLAGS = -mno-cygwin EXTRADLLFLAGS = -mno-cygwin

View File

@ -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 CRITICAL_SECTION queues_section = { &queues_critsect_debug, -1, 0, 0, 0, 0 };
static LONG platform_lock; static LONG platform_lock;
static CO_MTA_USAGE_COOKIE mta_cookie;
static struct queue_handle *get_queue_obj(DWORD handle) static struct queue_handle *get_queue_obj(DWORD handle)
{ {
@ -1117,6 +1118,7 @@ HRESULT WINAPI RtwqUnlockPlatform(void)
static void init_system_queues(void) static void init_system_queues(void)
{ {
struct queue_desc desc; struct queue_desc desc;
HRESULT hr;
/* Always initialize standard queue, keep the rest lazy. */ /* Always initialize standard queue, keep the rest lazy. */
@ -1128,6 +1130,9 @@ static void init_system_queues(void)
return; return;
} }
if (FAILED(hr = CoIncrementMTAUsage(&mta_cookie)))
WARN("Failed to initialize MTA, hr %#x.\n", hr);
desc.queue_type = RTWQ_STANDARD_WORKQUEUE; desc.queue_type = RTWQ_STANDARD_WORKQUEUE;
desc.ops = &pool_queue_ops; desc.ops = &pool_queue_ops;
desc.target_queue = 0; desc.target_queue = 0;
@ -1149,6 +1154,7 @@ HRESULT WINAPI RtwqStartup(void)
static void shutdown_system_queues(void) static void shutdown_system_queues(void)
{ {
unsigned int i; unsigned int i;
HRESULT hr;
EnterCriticalSection(&queues_section); EnterCriticalSection(&queues_section);
@ -1157,6 +1163,9 @@ static void shutdown_system_queues(void)
shutdown_queue(&system_queues[i]); shutdown_queue(&system_queues[i]);
} }
if (FAILED(hr = CoDecrementMTAUsage(mta_cookie)))
WARN("Failed to uninitialize MTA, hr %#x.\n", hr);
LeaveCriticalSection(&queues_section); LeaveCriticalSection(&queues_section);
} }

View File

@ -0,0 +1,5 @@
TESTDLL = rtworkq.dll
IMPORTS = rtworkq ole32
C_SRCS = \
rtworkq.c

View File

@ -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 <stdarg.h>
#include <string.h>
#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();
}