diff --git a/src/main.cpp b/src/main.cpp index 07cac147..79e770c1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -99,32 +99,20 @@ void mainThreadLoop(const std::shared_ptr> &shutdown_event) // Conditions that would require the main thread event loop #ifndef _WIN32 - run_loop = tray_is_enabled; // On Windows, tray runs in separate thread, so no main loop needed for tray + run_loop = tray_is_enabled && config::sunshine.system_tray; // On Windows, tray runs in separate thread, so no main loop needed for tray #endif if (!run_loop) { BOOST_LOG(info) << "No main thread features enabled, skipping event loop"sv; + // Wait for shutdown + shutdown_event->view(); return; } // Main thread event loop BOOST_LOG(info) << "Starting main loop"sv; - while (true) { - if (shutdown_event->peek()) { - BOOST_LOG(info) << "Shutdown event detected, breaking main loop"sv; - if (tray_is_enabled && config::sunshine.system_tray) { - system_tray::end_tray(); - } - break; - } - - if (tray_is_enabled) { - system_tray::process_tray_events(); - } - - // Sleep to avoid busy waiting - std::this_thread::sleep_for(std::chrono::milliseconds(50)); - } + while (system_tray::process_tray_events() == 0); + BOOST_LOG(info) << "Main loop has exited"sv; } int main(int argc, char *argv[]) { @@ -297,7 +285,10 @@ int main(int argc, char *argv[]) { }; force_shutdown = task_pool.pushDelayed(task, 10s).task_id; + // Break out of the main loop shutdown_event->raise(true); + system_tray::end_tray(); + display_device_deinit_guard = nullptr; }); @@ -311,7 +302,10 @@ int main(int argc, char *argv[]) { }; force_shutdown = task_pool.pushDelayed(task, 10s).task_id; + // Break out of the main loop shutdown_event->raise(true); + system_tray::end_tray(); + display_device_deinit_guard = nullptr; }); @@ -400,9 +394,6 @@ int main(int argc, char *argv[]) { mainThreadLoop(shutdown_event); - // Wait for shutdown, this is not necessary when we're using the main event loop - shutdown_event->view(); - httpThread.join(); configThread.join(); rtspThread.join(); @@ -416,11 +407,6 @@ int main(int argc, char *argv[]) { nvprefs_instance.restore_global_profile(); nvprefs_instance.unload(); } - - // Stop the threaded tray if it was started - if (tray_is_enabled && config::sunshine.system_tray) { - system_tray::end_tray_threaded(); - } #endif return lifetime::desired_exit_code; diff --git a/src/system_tray.cpp b/src/system_tray.cpp index e2bfa239..7d938bbb 100644 --- a/src/system_tray.cpp +++ b/src/system_tray.cpp @@ -53,11 +53,6 @@ using namespace std::literals; namespace system_tray { static std::atomic tray_initialized = false; - // Threading variables for all platforms - static std::thread tray_thread; - static std::atomic tray_thread_running = false; - static std::atomic tray_thread_should_exit = false; - void tray_open_ui_cb([[maybe_unused]] struct tray_menu *item) { BOOST_LOG(info) << "Opening UI from system tray"sv; launch_ui(); @@ -207,16 +202,12 @@ namespace system_tray { int process_tray_events() { if (!tray_initialized) { + BOOST_LOG(error) << "System tray is not initialized"sv; return 1; } - // Process one iteration of the tray loop with non-blocking mode (0) - if (const int result = tray_loop(0); result != 0) { - BOOST_LOG(warning) << "System tray loop failed"sv; - return result; - } - - return 0; + // Block until an event is processed or tray_quit() is called + return tray_loop(1); } int end_tray() { @@ -319,63 +310,22 @@ namespace system_tray { // Initialize the tray in this thread if (init_tray() != 0) { BOOST_LOG(error) << "Failed to initialize tray in thread"sv; - tray_thread_running = false; return; } - tray_thread_running = true; - // Main tray event loop - while (!tray_thread_should_exit) { - if (process_tray_events() != 0) { - BOOST_LOG(warning) << "Tray event processing failed in thread"sv; - break; - } + while (process_tray_events() == 0); - // Sleep to avoid busy waiting - std::this_thread::sleep_for(std::chrono::milliseconds(50)); - } - - // Clean up the tray - end_tray(); - tray_thread_running = false; BOOST_LOG(info) << "System tray thread ended"sv; } int init_tray_threaded() { - if (tray_thread_running) { - BOOST_LOG(warning) << "Tray thread is already running"sv; - return 1; - } - - tray_thread_should_exit = false; - try { - tray_thread = std::thread(tray_thread_worker); + auto tray_thread = std::thread(tray_thread_worker); - // Wait for the thread to start and initialize - const auto start_time = std::chrono::steady_clock::now(); - while (!tray_thread_running && !tray_thread_should_exit) { - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - - // Timeout after 10 seconds - if (std::chrono::steady_clock::now() - start_time > std::chrono::seconds(10)) { - BOOST_LOG(error) << "Tray thread initialization timeout"sv; - tray_thread_should_exit = true; - if (tray_thread.joinable()) { - tray_thread.join(); - } - return 1; - } - } - - if (!tray_thread_running) { - BOOST_LOG(error) << "Tray thread failed to start"sv; - if (tray_thread.joinable()) { - tray_thread.join(); - } - return 1; - } + // The tray thread doesn't require strong lifetime management. + // It will exit asynchronously when tray_exit() is called. + tray_thread.detach(); BOOST_LOG(info) << "System tray thread initialized successfully"sv; return 0; @@ -385,21 +335,5 @@ namespace system_tray { } } - int end_tray_threaded() { - if (!tray_thread_running) { - return 0; - } - - BOOST_LOG(info) << "Stopping system tray thread"sv; - tray_thread_should_exit = true; - - if (tray_thread.joinable()) { - tray_thread.join(); - } - - BOOST_LOG(info) << "System tray thread stopped"sv; - return 0; - } - } // namespace system_tray #endif diff --git a/src/system_tray.h b/src/system_tray.h index b96997e9..2a1cd1b4 100644 --- a/src/system_tray.h +++ b/src/system_tray.h @@ -96,10 +96,4 @@ namespace system_tray { * @return 0 if initialization was successful, non-zero otherwise. */ int init_tray_threaded(); - - /** - * @brief Stops the threaded system tray and waits for the thread to finish. - * @return 0 after stopping the threaded tray. - */ - int end_tray_threaded(); } // namespace system_tray diff --git a/third-party/tray b/third-party/tray index d43f4c24..4caf0d08 160000 --- a/third-party/tray +++ b/third-party/tray @@ -1 +1 @@ -Subproject commit d43f4c24d60d2fc7ed7e4fac178fa12f72145087 +Subproject commit 4caf0d0868aa45b98373249db8761551f7da7b03