Skip to content

Commit

Permalink
8294699: Launcher causes lingering busy cursor
Browse files Browse the repository at this point in the history
Backport-of: d3df3eb5d7f5537ade917db7a36caba028f94111
  • Loading branch information
TheRealMDoerr committed May 28, 2024
1 parent f4da0e7 commit 0cfee92
Showing 1 changed file with 78 additions and 2 deletions.
80 changes: 78 additions & 2 deletions src/jdk.jpackage/windows/native/applauncher/WinLauncher.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -134,6 +134,82 @@ tstring getJvmLibPath(const Jvm& jvm) {
}


class RunExecutorWithMsgLoop {
public:
static DWORD apply(const Executor& exec) {
RunExecutorWithMsgLoop instance(exec);

UniqueHandle threadHandle = UniqueHandle(CreateThread(NULL, 0, worker,
static_cast<LPVOID>(&instance), 0, NULL));
if (threadHandle.get() == NULL) {
JP_THROW(SysError("CreateThread() failed", CreateThread));
}

MSG msg;
BOOL bRet;
while((bRet = GetMessage(&msg, instance.hwnd, 0, 0 )) != 0) {
if (bRet == -1) {
JP_THROW(SysError("GetMessage() failed", GetMessage));
} else {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

// Wait for worker thread to terminate to guarantee it will not linger
// around after the thread running a message loop terminates.
const DWORD res = ::WaitForSingleObject(threadHandle.get(), INFINITE);
if (WAIT_FAILED == res) {
JP_THROW(SysError("WaitForSingleObject() failed",
WaitForSingleObject));
}

LOG_TRACE(tstrings::any()
<< "Executor worker thread terminated. Exit code="
<< instance.exitCode);
return instance.exitCode;
}

private:
RunExecutorWithMsgLoop(const Executor& v): exec(v) {
exitCode = 1;

// Message-only window.
hwnd = CreateWindowEx(0, _T("STATIC"), _T(""), 0, 0, 0, 0, 0,
HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL);
if (!hwnd) {
JP_THROW(SysError("CreateWindowEx() failed", CreateWindowEx));
}
}

static DWORD WINAPI worker(LPVOID param) {
static_cast<RunExecutorWithMsgLoop*>(param)->run();
return 0;
}

void run() {
JP_TRY;
exitCode = static_cast<DWORD>(exec.execAndWaitForExit());
JP_CATCH_ALL;

JP_TRY;
if (!PostMessage(hwnd, WM_QUIT, 0, 0)) {
JP_THROW(SysError("PostMessage(WM_QUIT) failed", PostMessage));
}
return;
JP_CATCH_ALL;

// All went wrong, PostMessage() failed. Just terminate with error code.
exit(1);
}

private:
const Executor& exec;
DWORD exitCode;
HWND hwnd;
};


void launchApp() {
// [RT-31061] otherwise UI can be left in back of other windows.
::AllowSetForegroundWindow(ASFW_ANY);
Expand Down Expand Up @@ -180,7 +256,7 @@ void launchApp() {
exec.arg(arg);
});

DWORD exitCode = static_cast<DWORD>(exec.execAndWaitForExit());
DWORD exitCode = RunExecutorWithMsgLoop::apply(exec);

exit(exitCode);
return;
Expand Down

1 comment on commit 0cfee92

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.