ole32/tests: Extend the lifecycle tests to objects which expose IExternalConnection.
This commit is contained in:
parent
e47edf47fe
commit
14a879085e
|
@ -46,6 +46,9 @@ static HRESULT (WINAPI *pDllGetClassObject)(REFCLSID,REFIID,LPVOID);
|
|||
#define ok_more_than_one_lock() ok(cLocks > 0, "Number of locks should be > 0, but actually is %d\n", cLocks)
|
||||
#define ok_no_locks() ok(cLocks == 0, "Number of locks should be 0, but actually is %d\n", cLocks)
|
||||
#define ok_ole_success(hr, func) ok(hr == S_OK, #func " failed with error 0x%08x\n", hr)
|
||||
#define ok_non_zero_external_conn() do {if (with_external_conn) ok(external_connections, "got no external connections\n");} while(0);
|
||||
#define ok_zero_external_conn() do {if (with_external_conn) ok(!external_connections, "got %d external connections\n", external_connections);} while(0);
|
||||
#define ok_last_release_closes(b) do {if (with_external_conn) ok(last_release_closes == b, "got %d expected %d\n", last_release_closes, b);} while(0);
|
||||
|
||||
static const IID IID_IWineTest =
|
||||
{
|
||||
|
@ -382,6 +385,7 @@ static void test_normal_marshal_and_release(void)
|
|||
IStream *pStream = NULL;
|
||||
|
||||
cLocks = 0;
|
||||
external_connections = 0;
|
||||
|
||||
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
|
||||
ok_ole_success(hr, CreateStreamOnHGlobal);
|
||||
|
@ -389,6 +393,7 @@ static void test_normal_marshal_and_release(void)
|
|||
ok_ole_success(hr, CoMarshalInterface);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_non_zero_external_conn();
|
||||
|
||||
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
|
||||
hr = CoReleaseMarshalData(pStream);
|
||||
|
@ -396,6 +401,8 @@ static void test_normal_marshal_and_release(void)
|
|||
IStream_Release(pStream);
|
||||
|
||||
ok_no_locks();
|
||||
ok_zero_external_conn();
|
||||
ok_last_release_closes(TRUE);
|
||||
}
|
||||
|
||||
/* tests success case of a same-thread marshal and unmarshal */
|
||||
|
@ -406,6 +413,7 @@ static void test_normal_marshal_and_unmarshal(void)
|
|||
IUnknown *pProxy = NULL;
|
||||
|
||||
cLocks = 0;
|
||||
external_connections = 0;
|
||||
|
||||
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
|
||||
ok_ole_success(hr, CreateStreamOnHGlobal);
|
||||
|
@ -413,6 +421,7 @@ static void test_normal_marshal_and_unmarshal(void)
|
|||
ok_ole_success(hr, CoMarshalInterface);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_non_zero_external_conn();
|
||||
|
||||
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
|
||||
hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
|
||||
|
@ -420,6 +429,9 @@ static void test_normal_marshal_and_unmarshal(void)
|
|||
IStream_Release(pStream);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_zero_external_conn();
|
||||
todo_wine
|
||||
ok_last_release_closes(FALSE);
|
||||
|
||||
IUnknown_Release(pProxy);
|
||||
|
||||
|
@ -437,18 +449,22 @@ static void test_marshal_and_unmarshal_invalid(void)
|
|||
HANDLE thread;
|
||||
|
||||
cLocks = 0;
|
||||
external_connections = 0;
|
||||
|
||||
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
|
||||
ok_ole_success(hr, CreateStreamOnHGlobal);
|
||||
tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &thread);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_non_zero_external_conn();
|
||||
|
||||
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
|
||||
hr = CoReleaseMarshalData(pStream);
|
||||
ok_ole_success(hr, CoReleaseMarshalData);
|
||||
|
||||
ok_no_locks();
|
||||
ok_zero_external_conn();
|
||||
ok_last_release_closes(TRUE);
|
||||
|
||||
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
|
||||
hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
|
||||
|
@ -477,6 +493,7 @@ static void test_same_apartment_unmarshal_failure(void)
|
|||
static const LARGE_INTEGER llZero;
|
||||
|
||||
cLocks = 0;
|
||||
external_connections = 0;
|
||||
|
||||
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
|
||||
ok_ole_success(hr, CreateStreamOnHGlobal);
|
||||
|
@ -485,6 +502,7 @@ static void test_same_apartment_unmarshal_failure(void)
|
|||
ok_ole_success(hr, CoMarshalInterface);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_non_zero_external_conn();
|
||||
|
||||
hr = IStream_Seek(pStream, llZero, STREAM_SEEK_SET, NULL);
|
||||
ok_ole_success(hr, IStream_Seek);
|
||||
|
@ -493,6 +511,9 @@ static void test_same_apartment_unmarshal_failure(void)
|
|||
ok(hr == E_NOINTERFACE, "CoUnmarshalInterface should have returned E_NOINTERFACE instead of 0x%08x\n", hr);
|
||||
|
||||
ok_no_locks();
|
||||
ok_zero_external_conn();
|
||||
todo_wine
|
||||
ok_last_release_closes(FALSE);
|
||||
|
||||
IStream_Release(pStream);
|
||||
}
|
||||
|
@ -507,12 +528,14 @@ static void test_interthread_marshal_and_unmarshal(void)
|
|||
HANDLE thread;
|
||||
|
||||
cLocks = 0;
|
||||
external_connections = 0;
|
||||
|
||||
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
|
||||
ok_ole_success(hr, CreateStreamOnHGlobal);
|
||||
tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &thread);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_non_zero_external_conn();
|
||||
|
||||
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
|
||||
hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
|
||||
|
@ -520,10 +543,13 @@ static void test_interthread_marshal_and_unmarshal(void)
|
|||
IStream_Release(pStream);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_non_zero_external_conn();
|
||||
|
||||
IUnknown_Release(pProxy);
|
||||
|
||||
ok_no_locks();
|
||||
ok_zero_external_conn();
|
||||
ok_last_release_closes(TRUE);
|
||||
|
||||
end_host_object(tid, thread);
|
||||
}
|
||||
|
@ -544,12 +570,14 @@ static void test_proxy_marshal_and_unmarshal(void)
|
|||
int i;
|
||||
|
||||
cLocks = 0;
|
||||
external_connections = 0;
|
||||
|
||||
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
|
||||
ok_ole_success(hr, CreateStreamOnHGlobal);
|
||||
tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &thread);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_non_zero_external_conn();
|
||||
|
||||
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
|
||||
hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
|
||||
|
@ -582,6 +610,7 @@ static void test_proxy_marshal_and_unmarshal(void)
|
|||
ok_ole_success(hr, CoUnmarshalInterface);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_non_zero_external_conn();
|
||||
|
||||
IUnknown_Release(pProxy2);
|
||||
|
||||
|
@ -595,6 +624,8 @@ static void test_proxy_marshal_and_unmarshal(void)
|
|||
}
|
||||
|
||||
ok_no_locks();
|
||||
ok_zero_external_conn();
|
||||
ok_last_release_closes(TRUE);
|
||||
|
||||
IStream_Release(pStream);
|
||||
|
||||
|
@ -613,12 +644,14 @@ static void test_proxy_marshal_and_unmarshal2(void)
|
|||
HANDLE thread;
|
||||
|
||||
cLocks = 0;
|
||||
external_connections = 0;
|
||||
|
||||
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
|
||||
ok_ole_success(hr, CreateStreamOnHGlobal);
|
||||
tid = start_host_object(pStream, &IID_IUnknown, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &thread);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_non_zero_external_conn();
|
||||
|
||||
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
|
||||
hr = CoUnmarshalInterface(pStream, &IID_IUnknown, (void **)&pProxy);
|
||||
|
@ -653,10 +686,13 @@ static void test_proxy_marshal_and_unmarshal2(void)
|
|||
IUnknown_Release(pProxy);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_non_zero_external_conn();
|
||||
|
||||
IUnknown_Release(pProxy2);
|
||||
|
||||
ok_no_locks();
|
||||
ok_zero_external_conn();
|
||||
ok_last_release_closes(TRUE);
|
||||
|
||||
end_host_object(tid, thread);
|
||||
}
|
||||
|
@ -672,18 +708,21 @@ static void test_proxy_marshal_and_unmarshal_weak(void)
|
|||
HANDLE thread;
|
||||
|
||||
cLocks = 0;
|
||||
external_connections = 0;
|
||||
|
||||
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
|
||||
ok_ole_success(hr, CreateStreamOnHGlobal);
|
||||
tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &thread);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_non_zero_external_conn();
|
||||
|
||||
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
|
||||
hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
|
||||
ok_ole_success(hr, CoUnmarshalInterface);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_non_zero_external_conn();
|
||||
|
||||
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
|
||||
/* marshal the proxy */
|
||||
|
@ -691,6 +730,7 @@ static void test_proxy_marshal_and_unmarshal_weak(void)
|
|||
ok_ole_success(hr, CoMarshalInterface);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_non_zero_external_conn();
|
||||
|
||||
/* release the original proxy to test that we successfully keep the
|
||||
* original object alive */
|
||||
|
@ -702,6 +742,8 @@ static void test_proxy_marshal_and_unmarshal_weak(void)
|
|||
ok(hr == CO_E_OBJNOTREG, "CoUnmarshalInterface should return CO_E_OBJNOTREG instead of 0x%08x\n", hr);
|
||||
|
||||
ok_no_locks();
|
||||
ok_zero_external_conn();
|
||||
ok_last_release_closes(TRUE);
|
||||
|
||||
IStream_Release(pStream);
|
||||
|
||||
|
@ -719,18 +761,21 @@ static void test_proxy_marshal_and_unmarshal_strong(void)
|
|||
HANDLE thread;
|
||||
|
||||
cLocks = 0;
|
||||
external_connections = 0;
|
||||
|
||||
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
|
||||
ok_ole_success(hr, CreateStreamOnHGlobal);
|
||||
tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &thread);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_non_zero_external_conn();
|
||||
|
||||
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
|
||||
hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
|
||||
ok_ole_success(hr, CoUnmarshalInterface);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_non_zero_external_conn();
|
||||
|
||||
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
|
||||
/* marshal the proxy */
|
||||
|
@ -744,6 +789,7 @@ static void test_proxy_marshal_and_unmarshal_strong(void)
|
|||
}
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_non_zero_external_conn();
|
||||
|
||||
/* release the original proxy to test that we successfully keep the
|
||||
* original object alive */
|
||||
|
@ -754,10 +800,12 @@ static void test_proxy_marshal_and_unmarshal_strong(void)
|
|||
ok_ole_success(hr, CoUnmarshalInterface);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_non_zero_external_conn();
|
||||
|
||||
IUnknown_Release(pProxy2);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_non_zero_external_conn();
|
||||
|
||||
end:
|
||||
IStream_Release(pStream);
|
||||
|
@ -765,6 +813,10 @@ end:
|
|||
end_host_object(tid, thread);
|
||||
|
||||
ok_no_locks();
|
||||
todo_wine {
|
||||
ok_zero_external_conn();
|
||||
ok_last_release_closes(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
/* tests that stubs are released when the containing apartment is destroyed */
|
||||
|
@ -777,12 +829,14 @@ static void test_marshal_stub_apartment_shutdown(void)
|
|||
HANDLE thread;
|
||||
|
||||
cLocks = 0;
|
||||
external_connections = 0;
|
||||
|
||||
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
|
||||
ok_ole_success(hr, CreateStreamOnHGlobal);
|
||||
tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &thread);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_non_zero_external_conn();
|
||||
|
||||
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
|
||||
hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
|
||||
|
@ -790,10 +844,15 @@ static void test_marshal_stub_apartment_shutdown(void)
|
|||
IStream_Release(pStream);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_non_zero_external_conn();
|
||||
|
||||
end_host_object(tid, thread);
|
||||
|
||||
ok_no_locks();
|
||||
todo_wine {
|
||||
ok_zero_external_conn();
|
||||
ok_last_release_closes(FALSE);
|
||||
}
|
||||
|
||||
IUnknown_Release(pProxy);
|
||||
|
||||
|
@ -810,12 +869,14 @@ static void test_marshal_proxy_apartment_shutdown(void)
|
|||
HANDLE thread;
|
||||
|
||||
cLocks = 0;
|
||||
external_connections = 0;
|
||||
|
||||
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
|
||||
ok_ole_success(hr, CreateStreamOnHGlobal);
|
||||
tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &thread);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_non_zero_external_conn();
|
||||
|
||||
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
|
||||
hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
|
||||
|
@ -823,10 +884,13 @@ static void test_marshal_proxy_apartment_shutdown(void)
|
|||
IStream_Release(pStream);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_non_zero_external_conn();
|
||||
|
||||
CoUninitialize();
|
||||
|
||||
ok_no_locks();
|
||||
ok_zero_external_conn();
|
||||
ok_last_release_closes(TRUE);
|
||||
|
||||
IUnknown_Release(pProxy);
|
||||
|
||||
|
@ -850,12 +914,14 @@ static void test_marshal_proxy_mta_apartment_shutdown(void)
|
|||
pCoInitializeEx(NULL, COINIT_MULTITHREADED);
|
||||
|
||||
cLocks = 0;
|
||||
external_connections = 0;
|
||||
|
||||
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
|
||||
ok_ole_success(hr, CreateStreamOnHGlobal);
|
||||
tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_NORMAL, &thread);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_non_zero_external_conn();
|
||||
|
||||
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
|
||||
hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
|
||||
|
@ -863,10 +929,13 @@ static void test_marshal_proxy_mta_apartment_shutdown(void)
|
|||
IStream_Release(pStream);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_non_zero_external_conn();
|
||||
|
||||
CoUninitialize();
|
||||
|
||||
ok_no_locks();
|
||||
ok_zero_external_conn();
|
||||
ok_last_release_closes(TRUE);
|
||||
|
||||
IUnknown_Release(pProxy);
|
||||
|
||||
|
@ -916,6 +985,7 @@ static void test_no_couninitialize_server(void)
|
|||
struct ncu_params ncu_params;
|
||||
|
||||
cLocks = 0;
|
||||
external_connections = 0;
|
||||
|
||||
ncu_params.marshal_event = CreateEventA(NULL, TRUE, FALSE, NULL);
|
||||
ncu_params.unmarshal_event = CreateEventA(NULL, TRUE, FALSE, NULL);
|
||||
|
@ -928,6 +998,7 @@ static void test_no_couninitialize_server(void)
|
|||
|
||||
ok( !WaitForSingleObject(ncu_params.marshal_event, 10000), "wait timed out\n" );
|
||||
ok_more_than_one_lock();
|
||||
ok_non_zero_external_conn();
|
||||
|
||||
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
|
||||
hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy);
|
||||
|
@ -935,11 +1006,16 @@ static void test_no_couninitialize_server(void)
|
|||
IStream_Release(pStream);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_non_zero_external_conn();
|
||||
|
||||
SetEvent(ncu_params.unmarshal_event);
|
||||
ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
|
||||
|
||||
ok_no_locks();
|
||||
todo_wine {
|
||||
ok_zero_external_conn();
|
||||
ok_last_release_closes(FALSE);
|
||||
}
|
||||
|
||||
CloseHandle(thread);
|
||||
CloseHandle(ncu_params.marshal_event);
|
||||
|
@ -982,6 +1058,7 @@ static void test_no_couninitialize_client(void)
|
|||
struct ncu_params ncu_params;
|
||||
|
||||
cLocks = 0;
|
||||
external_connections = 0;
|
||||
|
||||
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
|
||||
ok_ole_success(hr, CreateStreamOnHGlobal);
|
||||
|
@ -993,6 +1070,7 @@ static void test_no_couninitialize_client(void)
|
|||
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_non_zero_external_conn();
|
||||
|
||||
thread = CreateThread(NULL, 0, no_couninitialize_client_proc, &ncu_params, 0, &tid);
|
||||
|
||||
|
@ -1000,6 +1078,8 @@ static void test_no_couninitialize_client(void)
|
|||
CloseHandle(thread);
|
||||
|
||||
ok_no_locks();
|
||||
ok_zero_external_conn();
|
||||
ok_last_release_closes(TRUE);
|
||||
|
||||
end_host_object(host_tid, host_thread);
|
||||
}
|
||||
|
@ -1015,34 +1095,49 @@ static void test_tableweak_marshal_and_unmarshal_twice(void)
|
|||
HANDLE thread;
|
||||
|
||||
cLocks = 0;
|
||||
external_connections = 0;
|
||||
|
||||
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
|
||||
ok_ole_success(hr, CreateStreamOnHGlobal);
|
||||
tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_TABLEWEAK, &thread);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_zero_external_conn();
|
||||
|
||||
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
|
||||
hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy1);
|
||||
ok_ole_success(hr, CoUnmarshalInterface);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_non_zero_external_conn();
|
||||
|
||||
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
|
||||
hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy2);
|
||||
IStream_Release(pStream);
|
||||
ok_ole_success(hr, CoUnmarshalInterface);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
|
||||
IUnknown_Release(pProxy1);
|
||||
ok_non_zero_external_conn();
|
||||
IUnknown_Release(pProxy2);
|
||||
ok_zero_external_conn();
|
||||
ok_last_release_closes(TRUE);
|
||||
|
||||
/* this line is shows the difference between weak and strong table marshaling:
|
||||
* weak has cLocks == 0
|
||||
* strong has cLocks > 0 */
|
||||
/* When IExternalConnection is present COM's lifetime management
|
||||
* behaviour is altered; the remaining weak ref prevents stub shutdown. */
|
||||
if (with_external_conn)
|
||||
{
|
||||
todo_wine
|
||||
ok_more_than_one_lock();
|
||||
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
|
||||
release_host_object(tid);
|
||||
}
|
||||
|
||||
/* Without IExternalConnection this line is shows the difference between weak and strong table marshaling
|
||||
* weak has cLocks == 0, strong has cLocks > 0. */
|
||||
ok_no_locks();
|
||||
|
||||
IStream_Release(pStream);
|
||||
end_host_object(tid, thread);
|
||||
}
|
||||
|
||||
|
@ -1057,18 +1152,21 @@ static void test_tableweak_marshal_releasedata1(void)
|
|||
HANDLE thread;
|
||||
|
||||
cLocks = 0;
|
||||
external_connections = 0;
|
||||
|
||||
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
|
||||
ok_ole_success(hr, CreateStreamOnHGlobal);
|
||||
tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_TABLEWEAK, &thread);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_zero_external_conn();
|
||||
|
||||
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
|
||||
hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy1);
|
||||
ok_ole_success(hr, CoUnmarshalInterface);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_non_zero_external_conn();
|
||||
|
||||
/* release the remaining reference on the object by calling
|
||||
* CoReleaseMarshalData in the hosting thread */
|
||||
|
@ -1076,6 +1174,7 @@ static void test_tableweak_marshal_releasedata1(void)
|
|||
release_host_object(tid);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_non_zero_external_conn();
|
||||
|
||||
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
|
||||
hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy2);
|
||||
|
@ -1083,15 +1182,22 @@ static void test_tableweak_marshal_releasedata1(void)
|
|||
IStream_Release(pStream);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_non_zero_external_conn();
|
||||
|
||||
IUnknown_Release(pProxy1);
|
||||
|
||||
if (pProxy2)
|
||||
{
|
||||
ok_non_zero_external_conn();
|
||||
IUnknown_Release(pProxy2);
|
||||
}
|
||||
|
||||
/* this line is shows the difference between weak and strong table marshaling:
|
||||
* weak has cLocks == 0
|
||||
* strong has cLocks > 0 */
|
||||
ok_no_locks();
|
||||
ok_zero_external_conn();
|
||||
ok_last_release_closes(TRUE);
|
||||
|
||||
end_host_object(tid, thread);
|
||||
}
|
||||
|
@ -1106,12 +1212,14 @@ static void test_tableweak_marshal_releasedata2(void)
|
|||
HANDLE thread;
|
||||
|
||||
cLocks = 0;
|
||||
external_connections = 0;
|
||||
|
||||
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
|
||||
ok_ole_success(hr, CreateStreamOnHGlobal);
|
||||
tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_TABLEWEAK, &thread);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_zero_external_conn();
|
||||
|
||||
/* release the remaining reference on the object by calling
|
||||
* CoReleaseMarshalData in the hosting thread */
|
||||
|
@ -1131,6 +1239,7 @@ static void test_tableweak_marshal_releasedata2(void)
|
|||
IStream_Release(pStream);
|
||||
|
||||
ok_no_locks();
|
||||
ok_zero_external_conn();
|
||||
|
||||
end_host_object(tid, thread);
|
||||
}
|
||||
|
@ -1166,7 +1275,15 @@ static DWORD CALLBACK weak_and_normal_marshal_thread_proc(void *p)
|
|||
while (WAIT_OBJECT_0 + 1 == MsgWaitForMultipleObjects(1, &hQuitEvent, FALSE, 10000, QS_ALLINPUT))
|
||||
{
|
||||
while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
|
||||
DispatchMessageA(&msg);
|
||||
{
|
||||
if (msg.hwnd == NULL && msg.message == RELEASEMARSHALDATA)
|
||||
{
|
||||
CoReleaseMarshalData(data->pStreamWeak);
|
||||
SetEvent((HANDLE)msg.lParam);
|
||||
}
|
||||
else
|
||||
DispatchMessageA(&msg);
|
||||
}
|
||||
}
|
||||
CloseHandle(hQuitEvent);
|
||||
|
||||
|
@ -1186,6 +1303,7 @@ static void test_tableweak_and_normal_marshal_and_unmarshal(void)
|
|||
struct weak_and_normal_marshal_data data;
|
||||
|
||||
cLocks = 0;
|
||||
external_connections = 0;
|
||||
|
||||
data.hReadyEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
|
||||
data.hQuitEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
|
||||
|
@ -1199,6 +1317,7 @@ static void test_tableweak_and_normal_marshal_and_unmarshal(void)
|
|||
CloseHandle(data.hReadyEvent);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_non_zero_external_conn();
|
||||
|
||||
IStream_Seek(data.pStreamWeak, ullZero, STREAM_SEEK_SET, NULL);
|
||||
hr = CoUnmarshalInterface(data.pStreamWeak, &IID_IClassFactory, (void **)&pProxyWeak);
|
||||
|
@ -1215,9 +1334,22 @@ static void test_tableweak_and_normal_marshal_and_unmarshal(void)
|
|||
IUnknown_Release(pProxyNormal);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_non_zero_external_conn();
|
||||
|
||||
IUnknown_Release(pProxyWeak);
|
||||
|
||||
ok_zero_external_conn();
|
||||
ok_last_release_closes(TRUE);
|
||||
|
||||
/* When IExternalConnection is present COM's lifetime management
|
||||
* behaviour is altered; the remaining weak ref prevents stub shutdown. */
|
||||
if (with_external_conn)
|
||||
{
|
||||
todo_wine
|
||||
ok_more_than_one_lock();
|
||||
IStream_Seek(data.pStreamWeak, ullZero, STREAM_SEEK_SET, NULL);
|
||||
release_host_object(tid);
|
||||
}
|
||||
ok_no_locks();
|
||||
|
||||
IStream_Release(data.pStreamWeak);
|
||||
|
@ -1239,12 +1371,14 @@ static void test_tablestrong_marshal_and_unmarshal_twice(void)
|
|||
HANDLE thread;
|
||||
|
||||
cLocks = 0;
|
||||
external_connections = 0;
|
||||
|
||||
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
|
||||
ok_ole_success(hr, CreateStreamOnHGlobal);
|
||||
tid = start_host_object(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHLFLAGS_TABLESTRONG, &thread);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_non_zero_external_conn();
|
||||
|
||||
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
|
||||
hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy1);
|
||||
|
@ -1273,6 +1407,8 @@ static void test_tablestrong_marshal_and_unmarshal_twice(void)
|
|||
IStream_Release(pStream);
|
||||
|
||||
ok_no_locks();
|
||||
ok_zero_external_conn();
|
||||
ok_last_release_closes(TRUE);
|
||||
|
||||
end_host_object(tid, thread);
|
||||
}
|
||||
|
@ -1284,17 +1420,20 @@ static void test_lock_object_external(void)
|
|||
IStream *pStream = NULL;
|
||||
|
||||
cLocks = 0;
|
||||
with_external_conn = TRUE;
|
||||
external_connections = 0;
|
||||
|
||||
/* test the stub manager creation aspect of CoLockObjectExternal when the
|
||||
* object hasn't been marshaled yet */
|
||||
CoLockObjectExternal((IUnknown*)&Test_ClassFactory, TRUE, TRUE);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_non_zero_external_conn();
|
||||
|
||||
CoDisconnectObject((IUnknown*)&Test_ClassFactory, 0);
|
||||
|
||||
ok_no_locks();
|
||||
ok_non_zero_external_conn();
|
||||
external_connections = 0;
|
||||
|
||||
/* test our empty stub manager being handled correctly in
|
||||
* CoMarshalInterface */
|
||||
|
@ -1308,6 +1447,7 @@ static void test_lock_object_external(void)
|
|||
CoLockObjectExternal((IUnknown*)&Test_ClassFactory, TRUE, TRUE);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_non_zero_external_conn();
|
||||
|
||||
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
|
||||
hr = CoReleaseMarshalData(pStream);
|
||||
|
@ -1315,15 +1455,20 @@ static void test_lock_object_external(void)
|
|||
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_non_zero_external_conn();
|
||||
ok_last_release_closes(TRUE);
|
||||
|
||||
CoLockObjectExternal((IUnknown*)&Test_ClassFactory, FALSE, TRUE);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_non_zero_external_conn();
|
||||
ok_last_release_closes(TRUE);
|
||||
|
||||
CoLockObjectExternal((IUnknown*)&Test_ClassFactory, FALSE, TRUE);
|
||||
|
||||
ok_no_locks();
|
||||
ok(last_release_closes, "last_release_closes FALSE\n");
|
||||
ok_zero_external_conn();
|
||||
ok_last_release_closes(TRUE);
|
||||
|
||||
/* test CoLockObjectExternal releases reference to object with
|
||||
* fLastUnlockReleases as TRUE and there are only strong references on
|
||||
|
@ -1331,12 +1476,14 @@ static void test_lock_object_external(void)
|
|||
CoLockObjectExternal((IUnknown*)&Test_ClassFactory, TRUE, FALSE);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_non_zero_external_conn();
|
||||
|
||||
CoLockObjectExternal((IUnknown*)&Test_ClassFactory, FALSE, FALSE);
|
||||
|
||||
ok_no_locks();
|
||||
ok_zero_external_conn();
|
||||
todo_wine
|
||||
ok(!last_release_closes, "last_release_closes TRUE\n");
|
||||
ok_last_release_closes(FALSE);
|
||||
|
||||
/* test CoLockObjectExternal doesn't release the last reference to an
|
||||
* object with fLastUnlockReleases as TRUE and there is a weak reference
|
||||
|
@ -1345,23 +1492,25 @@ todo_wine
|
|||
ok_ole_success(hr, CoMarshalInterface);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_zero_external_conn();
|
||||
|
||||
CoLockObjectExternal((IUnknown*)&Test_ClassFactory, TRUE, FALSE);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_non_zero_external_conn();
|
||||
|
||||
CoLockObjectExternal((IUnknown*)&Test_ClassFactory, FALSE, FALSE);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_zero_external_conn();
|
||||
todo_wine
|
||||
ok_last_release_closes(FALSE);
|
||||
|
||||
CoDisconnectObject((IUnknown*)&Test_ClassFactory, 0);
|
||||
|
||||
ok_no_locks();
|
||||
todo_wine
|
||||
ok(!last_release_closes, "last_release_closes TRUE\n");
|
||||
|
||||
IStream_Release(pStream);
|
||||
with_external_conn = FALSE;
|
||||
}
|
||||
|
||||
/* tests disconnecting stubs */
|
||||
|
@ -1371,15 +1520,19 @@ static void test_disconnect_stub(void)
|
|||
IStream *pStream = NULL;
|
||||
|
||||
cLocks = 0;
|
||||
external_connections = 0;
|
||||
|
||||
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
|
||||
ok_ole_success(hr, CreateStreamOnHGlobal);
|
||||
hr = CoMarshalInterface(pStream, &IID_IClassFactory, (IUnknown*)&Test_ClassFactory, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
|
||||
ok_ole_success(hr, CoMarshalInterface);
|
||||
|
||||
ok_non_zero_external_conn();
|
||||
|
||||
CoLockObjectExternal((IUnknown*)&Test_ClassFactory, TRUE, TRUE);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_non_zero_external_conn();
|
||||
|
||||
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
|
||||
hr = CoReleaseMarshalData(pStream);
|
||||
|
@ -1387,10 +1540,12 @@ static void test_disconnect_stub(void)
|
|||
IStream_Release(pStream);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_non_zero_external_conn();
|
||||
|
||||
CoDisconnectObject((IUnknown*)&Test_ClassFactory, 0);
|
||||
|
||||
ok_no_locks();
|
||||
ok_non_zero_external_conn();
|
||||
|
||||
hr = CoDisconnectObject(NULL, 0);
|
||||
ok( hr == E_INVALIDARG, "wrong status %x\n", hr );
|
||||
|
@ -1405,6 +1560,7 @@ static void test_normal_marshal_and_unmarshal_twice(void)
|
|||
IUnknown *pProxy2 = NULL;
|
||||
|
||||
cLocks = 0;
|
||||
external_connections = 0;
|
||||
|
||||
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
|
||||
ok_ole_success(hr, CreateStreamOnHGlobal);
|
||||
|
@ -1412,12 +1568,16 @@ static void test_normal_marshal_and_unmarshal_twice(void)
|
|||
ok_ole_success(hr, CoMarshalInterface);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_non_zero_external_conn();
|
||||
|
||||
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
|
||||
hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy1);
|
||||
ok_ole_success(hr, CoUnmarshalInterface);
|
||||
|
||||
ok_more_than_one_lock();
|
||||
ok_zero_external_conn();
|
||||
todo_wine
|
||||
ok_last_release_closes(FALSE);
|
||||
|
||||
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
|
||||
hr = CoUnmarshalInterface(pStream, &IID_IClassFactory, (void **)&pProxy2);
|
||||
|
@ -3250,29 +3410,35 @@ START_TEST(marshal)
|
|||
/* FIXME: test CoCreateInstanceEx */
|
||||
|
||||
/* lifecycle management and marshaling tests */
|
||||
test_no_marshaler();
|
||||
test_normal_marshal_and_release();
|
||||
test_normal_marshal_and_unmarshal();
|
||||
test_marshal_and_unmarshal_invalid();
|
||||
test_same_apartment_unmarshal_failure();
|
||||
test_interthread_marshal_and_unmarshal();
|
||||
test_proxy_marshal_and_unmarshal();
|
||||
test_proxy_marshal_and_unmarshal2();
|
||||
test_proxy_marshal_and_unmarshal_weak();
|
||||
test_proxy_marshal_and_unmarshal_strong();
|
||||
test_marshal_stub_apartment_shutdown();
|
||||
test_marshal_proxy_apartment_shutdown();
|
||||
test_marshal_proxy_mta_apartment_shutdown();
|
||||
test_no_couninitialize_server();
|
||||
test_no_couninitialize_client();
|
||||
test_tableweak_marshal_and_unmarshal_twice();
|
||||
test_tableweak_marshal_releasedata1();
|
||||
test_tableweak_marshal_releasedata2();
|
||||
test_tableweak_and_normal_marshal_and_unmarshal();
|
||||
test_tablestrong_marshal_and_unmarshal_twice();
|
||||
test_lock_object_external();
|
||||
test_disconnect_stub();
|
||||
test_normal_marshal_and_unmarshal_twice();
|
||||
do
|
||||
{
|
||||
test_no_marshaler();
|
||||
test_normal_marshal_and_release();
|
||||
test_normal_marshal_and_unmarshal();
|
||||
test_marshal_and_unmarshal_invalid();
|
||||
test_same_apartment_unmarshal_failure();
|
||||
test_interthread_marshal_and_unmarshal();
|
||||
test_proxy_marshal_and_unmarshal();
|
||||
test_proxy_marshal_and_unmarshal2();
|
||||
test_proxy_marshal_and_unmarshal_weak();
|
||||
test_proxy_marshal_and_unmarshal_strong();
|
||||
test_marshal_stub_apartment_shutdown();
|
||||
test_marshal_proxy_apartment_shutdown();
|
||||
test_marshal_proxy_mta_apartment_shutdown();
|
||||
test_no_couninitialize_server();
|
||||
test_no_couninitialize_client();
|
||||
test_tableweak_marshal_and_unmarshal_twice();
|
||||
test_tableweak_marshal_releasedata1();
|
||||
test_tableweak_marshal_releasedata2();
|
||||
test_tableweak_and_normal_marshal_and_unmarshal();
|
||||
test_tablestrong_marshal_and_unmarshal_twice();
|
||||
test_lock_object_external();
|
||||
test_disconnect_stub();
|
||||
test_normal_marshal_and_unmarshal_twice();
|
||||
|
||||
with_external_conn = !with_external_conn;
|
||||
} while (with_external_conn);
|
||||
|
||||
test_hresult_marshaling();
|
||||
test_proxy_used_in_wrong_thread();
|
||||
test_message_filter();
|
||||
|
|
Loading…
Reference in New Issue