Skip to content

Commit 4df4655

Browse files
author
sergei
authored
[SYCL] Only call shutdown when DLL is being unloaded, not when process is terminating (#4983)
Signed-off-by: Sergey Kanaev <sergey.kanaev@intel.com>
1 parent 64720d8 commit 4df4655

File tree

4 files changed

+72
-1
lines changed

4 files changed

+72
-1
lines changed

sycl/source/detail/global_handler.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,8 @@ extern "C" __SYCL_EXPORT BOOL WINAPI DllMain(HINSTANCE hinstDLL,
164164
// Perform actions based on the reason for calling.
165165
switch (fdwReason) {
166166
case DLL_PROCESS_DETACH:
167-
shutdown();
167+
if (!lpReserved)
168+
shutdown();
168169
break;
169170
case DLL_PROCESS_ATTACH:
170171
case DLL_THREAD_ATTACH:

sycl/unittests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,4 @@ add_subdirectory(thread_safety)
2424
add_subdirectory(program_manager)
2525
add_subdirectory(assert)
2626
add_subdirectory(Extensions)
27+
add_subdirectory(windows)

sycl/unittests/windows/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
add_sycl_unittest(WindowsDllMainTest OBJECT
2+
dllmain.cpp
3+
)
4+

sycl/unittests/windows/dllmain.cpp

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
//==----- dllmain.cpp --- verify behaviour of lib on process termination ---==//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
/*
10+
* This test calls DllMain on Windows. This means, the process performs actions
11+
* which are required for library unload. That said, the test requires to be a
12+
* distinct binary executable.
13+
*/
14+
15+
#include <CL/sycl.hpp>
16+
#include <helpers/CommonRedefinitions.hpp>
17+
#include <helpers/PiImage.hpp>
18+
#include <helpers/PiMock.hpp>
19+
20+
#include <gtest/gtest.h>
21+
22+
#ifdef _WIN32
23+
#include <windows.h>
24+
25+
extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason,
26+
LPVOID lpReserved);
27+
28+
static std::atomic<int> TearDownCalls{0};
29+
30+
pi_result redefinedTearDown(void *PluginParameter) {
31+
fprintf(stderr, "intercepted tear down\n");
32+
++TearDownCalls;
33+
34+
return PI_SUCCESS;
35+
}
36+
#endif
37+
38+
TEST(Windows, DllMainCall) {
39+
#ifdef _WIN32
40+
sycl::platform Plt{sycl::default_selector()};
41+
if (Plt.is_host()) {
42+
printf("Test is not supported on host, skipping\n");
43+
return;
44+
}
45+
sycl::unittest::PiMock Mock{Plt};
46+
setupDefaultMockAPIs(Mock);
47+
Mock.redefine<sycl::detail::PiApiKind::piTearDown>(redefinedTearDown);
48+
49+
// Teardown calls are only expected on sycl.dll library unload, not when
50+
// process gets terminated.
51+
// The first call to DllMain is to simulate library unload. The second one
52+
// is to simulate process termination
53+
fprintf(stderr, "Call DllMain for the first time\n");
54+
DllMain((HINSTANCE)0, DLL_PROCESS_DETACH, (LPVOID)NULL);
55+
56+
int TearDownCallsDone = TearDownCalls.load();
57+
58+
EXPECT_NE(TearDownCallsDone, 0);
59+
60+
fprintf(stderr, "Call DllMain for the second time\n");
61+
DllMain((HINSTANCE)0, DLL_PROCESS_DETACH, (LPVOID)0x01);
62+
63+
EXPECT_EQ(TearDownCalls.load(), TearDownCallsDone);
64+
#endif
65+
}

0 commit comments

Comments
 (0)