combase: Manage per-thread call cancellation counter.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2020-09-16 16:02:40 +03:00 committed by Alexandre Julliard
parent 49eac508b5
commit 609c311a81
5 changed files with 85 additions and 4 deletions

View File

@ -3104,9 +3104,20 @@ HRESULT WINAPI CoRegisterChannelHook(REFGUID guidExtension, IChannelHook *channe
*/
HRESULT WINAPI CoDisableCallCancellation(void *reserved)
{
FIXME("%p stub\n", reserved);
struct tlsdata *tlsdata;
HRESULT hr;
return E_NOTIMPL;
TRACE("%p\n", reserved);
if (FAILED(hr = com_get_tlsdata(&tlsdata)))
return hr;
if (!tlsdata->cancelcount)
return CO_E_CANCEL_DISABLED;
tlsdata->cancelcount--;
return S_OK;
}
/***********************************************************************
@ -3114,9 +3125,17 @@ HRESULT WINAPI CoDisableCallCancellation(void *reserved)
*/
HRESULT WINAPI CoEnableCallCancellation(void *reserved)
{
FIXME("%p stub\n", reserved);
struct tlsdata *tlsdata;
HRESULT hr;
return E_NOTIMPL;
TRACE("%p\n", reserved);
if (FAILED(hr = com_get_tlsdata(&tlsdata)))
return hr;
tlsdata->cancelcount++;
return S_OK;
}
/***********************************************************************

View File

@ -84,6 +84,7 @@ struct tlsdata
IUnknown *state; /* see CoSetState */
struct list spies; /* Spies installed with CoRegisterInitializeSpy */
DWORD spies_lock;
DWORD cancelcount;
};
extern HRESULT WINAPI InternalTlsAllocData(struct tlsdata **data);

View File

@ -62,6 +62,7 @@ struct oletls
IUnknown *state; /* see CoSetState */
struct list spies; /* Spies installed with CoRegisterInitializeSpy */
DWORD spies_lock;
DWORD cancelcount;
};
/* Global Interface Table Functions */

View File

@ -4186,6 +4186,64 @@ todo_wine
CoUninitialize();
}
static void test_call_cancellation(void)
{
HRESULT hr;
/* Cancellation is disabled initially. */
hr = CoDisableCallCancellation(NULL);
ok(hr == CO_E_CANCEL_DISABLED, "Unexpected hr %#x.\n", hr);
hr = CoEnableCallCancellation(NULL);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
hr = CoDisableCallCancellation(NULL);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
hr = CoDisableCallCancellation(NULL);
ok(hr == CO_E_CANCEL_DISABLED, "Unexpected hr %#x.\n", hr);
hr = CoEnableCallCancellation(NULL);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
/* Counter is not affected by initialization. */
hr = CoInitialize(NULL);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
hr = CoDisableCallCancellation(NULL);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
hr = CoDisableCallCancellation(NULL);
ok(hr == CO_E_CANCEL_DISABLED, "Unexpected hr %#x.\n", hr);
hr = CoEnableCallCancellation(NULL);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
CoUninitialize();
hr = CoDisableCallCancellation(NULL);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
hr = CoDisableCallCancellation(NULL);
ok(hr == CO_E_CANCEL_DISABLED, "Unexpected hr %#x.\n", hr);
/* It's cumulative. */
hr = CoEnableCallCancellation(NULL);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
hr = CoEnableCallCancellation(NULL);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
hr = CoDisableCallCancellation(NULL);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
hr = CoDisableCallCancellation(NULL);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
hr = CoDisableCallCancellation(NULL);
ok(hr == CO_E_CANCEL_DISABLED, "Unexpected hr %#x.\n", hr);
}
START_TEST(compobj)
{
init_funcs();
@ -4236,6 +4294,7 @@ START_TEST(compobj)
test_CoGetCurrentProcess();
test_mta_usage();
test_CoCreateInstanceFromApp();
test_call_cancellation();
DeleteFileA( testlib );
}

View File

@ -2679,6 +2679,7 @@ static inline HRESULT HRESULT_FROM_WIN32(unsigned int x)
#define RPC_E_NO_CONTEXT _HRESULT_TYPEDEF_(0x8001011E)
#define RPC_E_TIMEOUT _HRESULT_TYPEDEF_(0x8001011F)
#define RPC_E_NO_SYNC _HRESULT_TYPEDEF_(0x80010120)
#define CO_E_CANCEL_DISABLED _HRESULT_TYPEDEF_(0x80010140)
#define RPC_E_UNEXPECTED _HRESULT_TYPEDEF_(0x8001FFFF)
#define DISP_E_UNKNOWNINTERFACE _HRESULT_TYPEDEF_(0x80020001)