Skip to content

Commit 289bb59

Browse files
committed
8294699: Launcher causes lingering busy cursor
Backport-of: d3df3eb5d7f5537ade917db7a36caba028f94111
1 parent d31a531 commit 289bb59

File tree

1 file changed

+78
-2
lines changed

1 file changed

+78
-2
lines changed

src/jdk.jpackage/windows/native/applauncher/WinLauncher.cpp

Lines changed: 78 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -134,6 +134,82 @@ tstring getJvmLibPath(const Jvm& jvm) {
134134
}
135135

136136

137+
class RunExecutorWithMsgLoop {
138+
public:
139+
static DWORD apply(const Executor& exec) {
140+
RunExecutorWithMsgLoop instance(exec);
141+
142+
UniqueHandle threadHandle = UniqueHandle(CreateThread(NULL, 0, worker,
143+
static_cast<LPVOID>(&instance), 0, NULL));
144+
if (threadHandle.get() == NULL) {
145+
JP_THROW(SysError("CreateThread() failed", CreateThread));
146+
}
147+
148+
MSG msg;
149+
BOOL bRet;
150+
while((bRet = GetMessage(&msg, instance.hwnd, 0, 0 )) != 0) {
151+
if (bRet == -1) {
152+
JP_THROW(SysError("GetMessage() failed", GetMessage));
153+
} else {
154+
TranslateMessage(&msg);
155+
DispatchMessage(&msg);
156+
}
157+
}
158+
159+
// Wait for worker thread to terminate to guarantee it will not linger
160+
// around after the thread running a message loop terminates.
161+
const DWORD res = ::WaitForSingleObject(threadHandle.get(), INFINITE);
162+
if (WAIT_FAILED == res) {
163+
JP_THROW(SysError("WaitForSingleObject() failed",
164+
WaitForSingleObject));
165+
}
166+
167+
LOG_TRACE(tstrings::any()
168+
<< "Executor worker thread terminated. Exit code="
169+
<< instance.exitCode);
170+
return instance.exitCode;
171+
}
172+
173+
private:
174+
RunExecutorWithMsgLoop(const Executor& v): exec(v) {
175+
exitCode = 1;
176+
177+
// Message-only window.
178+
hwnd = CreateWindowEx(0, _T("STATIC"), _T(""), 0, 0, 0, 0, 0,
179+
HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL);
180+
if (!hwnd) {
181+
JP_THROW(SysError("CreateWindowEx() failed", CreateWindowEx));
182+
}
183+
}
184+
185+
static DWORD WINAPI worker(LPVOID param) {
186+
static_cast<RunExecutorWithMsgLoop*>(param)->run();
187+
return 0;
188+
}
189+
190+
void run() {
191+
JP_TRY;
192+
exitCode = static_cast<DWORD>(exec.execAndWaitForExit());
193+
JP_CATCH_ALL;
194+
195+
JP_TRY;
196+
if (!PostMessage(hwnd, WM_QUIT, 0, 0)) {
197+
JP_THROW(SysError("PostMessage(WM_QUIT) failed", PostMessage));
198+
}
199+
return;
200+
JP_CATCH_ALL;
201+
202+
// All went wrong, PostMessage() failed. Just terminate with error code.
203+
exit(1);
204+
}
205+
206+
private:
207+
const Executor& exec;
208+
DWORD exitCode;
209+
HWND hwnd;
210+
};
211+
212+
137213
void launchApp() {
138214
// [RT-31061] otherwise UI can be left in back of other windows.
139215
::AllowSetForegroundWindow(ASFW_ANY);
@@ -180,7 +256,7 @@ void launchApp() {
180256
exec.arg(arg);
181257
});
182258

183-
DWORD exitCode = static_cast<DWORD>(exec.execAndWaitForExit());
259+
DWORD exitCode = RunExecutorWithMsgLoop::apply(exec);
184260

185261
exit(exitCode);
186262
return;

0 commit comments

Comments
 (0)