fix(tray): use the blocking event loop to avoid wasting power (#4457)
This commit is contained in:
36
src/main.cpp
36
src/main.cpp
@@ -99,32 +99,20 @@ void mainThreadLoop(const std::shared_ptr<safe::event_t<bool>> &shutdown_event)
|
|||||||
|
|
||||||
// Conditions that would require the main thread event loop
|
// Conditions that would require the main thread event loop
|
||||||
#ifndef _WIN32
|
#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
|
#endif
|
||||||
|
|
||||||
if (!run_loop) {
|
if (!run_loop) {
|
||||||
BOOST_LOG(info) << "No main thread features enabled, skipping event loop"sv;
|
BOOST_LOG(info) << "No main thread features enabled, skipping event loop"sv;
|
||||||
|
// Wait for shutdown
|
||||||
|
shutdown_event->view();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Main thread event loop
|
// Main thread event loop
|
||||||
BOOST_LOG(info) << "Starting main loop"sv;
|
BOOST_LOG(info) << "Starting main loop"sv;
|
||||||
while (true) {
|
while (system_tray::process_tray_events() == 0);
|
||||||
if (shutdown_event->peek()) {
|
BOOST_LOG(info) << "Main loop has exited"sv;
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
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;
|
force_shutdown = task_pool.pushDelayed(task, 10s).task_id;
|
||||||
|
|
||||||
|
// Break out of the main loop
|
||||||
shutdown_event->raise(true);
|
shutdown_event->raise(true);
|
||||||
|
system_tray::end_tray();
|
||||||
|
|
||||||
display_device_deinit_guard = nullptr;
|
display_device_deinit_guard = nullptr;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -311,7 +302,10 @@ int main(int argc, char *argv[]) {
|
|||||||
};
|
};
|
||||||
force_shutdown = task_pool.pushDelayed(task, 10s).task_id;
|
force_shutdown = task_pool.pushDelayed(task, 10s).task_id;
|
||||||
|
|
||||||
|
// Break out of the main loop
|
||||||
shutdown_event->raise(true);
|
shutdown_event->raise(true);
|
||||||
|
system_tray::end_tray();
|
||||||
|
|
||||||
display_device_deinit_guard = nullptr;
|
display_device_deinit_guard = nullptr;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -400,9 +394,6 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
mainThreadLoop(shutdown_event);
|
mainThreadLoop(shutdown_event);
|
||||||
|
|
||||||
// Wait for shutdown, this is not necessary when we're using the main event loop
|
|
||||||
shutdown_event->view();
|
|
||||||
|
|
||||||
httpThread.join();
|
httpThread.join();
|
||||||
configThread.join();
|
configThread.join();
|
||||||
rtspThread.join();
|
rtspThread.join();
|
||||||
@@ -416,11 +407,6 @@ int main(int argc, char *argv[]) {
|
|||||||
nvprefs_instance.restore_global_profile();
|
nvprefs_instance.restore_global_profile();
|
||||||
nvprefs_instance.unload();
|
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
|
#endif
|
||||||
|
|
||||||
return lifetime::desired_exit_code;
|
return lifetime::desired_exit_code;
|
||||||
|
|||||||
@@ -53,11 +53,6 @@ using namespace std::literals;
|
|||||||
namespace system_tray {
|
namespace system_tray {
|
||||||
static std::atomic tray_initialized = false;
|
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) {
|
void tray_open_ui_cb([[maybe_unused]] struct tray_menu *item) {
|
||||||
BOOST_LOG(info) << "Opening UI from system tray"sv;
|
BOOST_LOG(info) << "Opening UI from system tray"sv;
|
||||||
launch_ui();
|
launch_ui();
|
||||||
@@ -207,16 +202,12 @@ namespace system_tray {
|
|||||||
|
|
||||||
int process_tray_events() {
|
int process_tray_events() {
|
||||||
if (!tray_initialized) {
|
if (!tray_initialized) {
|
||||||
|
BOOST_LOG(error) << "System tray is not initialized"sv;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process one iteration of the tray loop with non-blocking mode (0)
|
// Block until an event is processed or tray_quit() is called
|
||||||
if (const int result = tray_loop(0); result != 0) {
|
return tray_loop(1);
|
||||||
BOOST_LOG(warning) << "System tray loop failed"sv;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int end_tray() {
|
int end_tray() {
|
||||||
@@ -319,63 +310,22 @@ namespace system_tray {
|
|||||||
// Initialize the tray in this thread
|
// Initialize the tray in this thread
|
||||||
if (init_tray() != 0) {
|
if (init_tray() != 0) {
|
||||||
BOOST_LOG(error) << "Failed to initialize tray in thread"sv;
|
BOOST_LOG(error) << "Failed to initialize tray in thread"sv;
|
||||||
tray_thread_running = false;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
tray_thread_running = true;
|
|
||||||
|
|
||||||
// Main tray event loop
|
// Main tray event loop
|
||||||
while (!tray_thread_should_exit) {
|
while (process_tray_events() == 0);
|
||||||
if (process_tray_events() != 0) {
|
|
||||||
BOOST_LOG(warning) << "Tray event processing failed in thread"sv;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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;
|
BOOST_LOG(info) << "System tray thread ended"sv;
|
||||||
}
|
}
|
||||||
|
|
||||||
int init_tray_threaded() {
|
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 {
|
try {
|
||||||
tray_thread = std::thread(tray_thread_worker);
|
auto tray_thread = std::thread(tray_thread_worker);
|
||||||
|
|
||||||
// Wait for the thread to start and initialize
|
// The tray thread doesn't require strong lifetime management.
|
||||||
const auto start_time = std::chrono::steady_clock::now();
|
// It will exit asynchronously when tray_exit() is called.
|
||||||
while (!tray_thread_running && !tray_thread_should_exit) {
|
tray_thread.detach();
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_LOG(info) << "System tray thread initialized successfully"sv;
|
BOOST_LOG(info) << "System tray thread initialized successfully"sv;
|
||||||
return 0;
|
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
|
} // namespace system_tray
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -96,10 +96,4 @@ namespace system_tray {
|
|||||||
* @return 0 if initialization was successful, non-zero otherwise.
|
* @return 0 if initialization was successful, non-zero otherwise.
|
||||||
*/
|
*/
|
||||||
int init_tray_threaded();
|
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
|
} // namespace system_tray
|
||||||
|
|||||||
2
third-party/tray
vendored
2
third-party/tray
vendored
Submodule third-party/tray updated: d43f4c24d6...4caf0d0868
Reference in New Issue
Block a user