Skip to content

Commit

Permalink
Properly join session monitor window thread
Browse files Browse the repository at this point in the history
  • Loading branch information
ns6089 authored and cgutman committed Oct 10, 2023
1 parent f1cd946 commit a564f4b
Showing 1 changed file with 40 additions and 2 deletions.
42 changes: 40 additions & 2 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,12 @@ std::map<std::string_view, std::function<int(const char *name, int argc, char **
LRESULT CALLBACK
SessionMonitorWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
case WM_CLOSE:
DestroyWindow(hwnd);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_ENDSESSION: {
// Terminate ourselves with a blocking exit call
std::cout << "Received WM_ENDSESSION"sv << std::endl;
Expand Down Expand Up @@ -613,11 +619,19 @@ main(int argc, char *argv[]) {
SetProcessShutdownParameters(0x100, SHUTDOWN_NORETRY);

// We must create a hidden window to receive shutdown notifications since we load gdi32.dll
std::thread window_thread([]() {
std::promise<HWND> session_monitor_hwnd_promise;
auto session_monitor_hwnd_future = session_monitor_hwnd_promise.get_future();
std::promise<void> session_monitor_join_thread_promise;
auto session_monitor_join_thread_future = session_monitor_join_thread_promise.get_future();

std::thread session_monitor_thread([&]() {
session_monitor_join_thread_promise.set_value_at_thread_exit();

WNDCLASSA wnd_class {};
wnd_class.lpszClassName = "SunshineSessionMonitorClass";
wnd_class.lpfnWndProc = SessionMonitorWindowProc;
if (!RegisterClassA(&wnd_class)) {
session_monitor_hwnd_promise.set_value(NULL);
BOOST_LOG(error) << "Failed to register session monitor window class"sv << std::endl;
return;
}
Expand All @@ -635,6 +649,9 @@ main(int argc, char *argv[]) {
nullptr,
nullptr,
nullptr);

session_monitor_hwnd_promise.set_value(wnd);

if (!wnd) {
BOOST_LOG(error) << "Failed to create session monitor window"sv << std::endl;
return;
Expand All @@ -649,7 +666,28 @@ main(int argc, char *argv[]) {
DispatchMessage(&msg);
}
});
window_thread.detach();

auto session_monitor_join_thread_guard = util::fail_guard([&]() {
if (session_monitor_hwnd_future.wait_for(1s) == std::future_status::ready) {
if (HWND session_monitor_hwnd = session_monitor_hwnd_future.get()) {
PostMessage(session_monitor_hwnd, WM_CLOSE, 0, 0);
}

if (session_monitor_join_thread_future.wait_for(1s) == std::future_status::ready) {
session_monitor_thread.join();
return;
}
else {
BOOST_LOG(warning) << "session_monitor_join_thread_future reached timeout";
}
}
else {
BOOST_LOG(warning) << "session_monitor_hwnd_future reached timeout";
}

session_monitor_thread.detach();
});

#endif

BOOST_LOG(info) << PROJECT_NAME << " version: " << PROJECT_VER << std::endl;
Expand Down

0 comments on commit a564f4b

Please sign in to comment.