Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 11 additions & 25 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,32 +99,20 @@

// 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);

Check warning on line 114 in src/main.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Suspicious semicolon.

See more on https://sonarcloud.io/project/issues?id=LizardByte_Sunshine&issues=AZrMSa0rwp9VPPRr28HH&open=AZrMSa0rwp9VPPRr28HH&pullRequest=4457
BOOST_LOG(info) << "Main loop has exited"sv;
}

int main(int argc, char *argv[]) {
Expand Down Expand Up @@ -297,7 +285,10 @@
};
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;
});

Expand All @@ -311,7 +302,10 @@
};
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;
});

Expand Down Expand Up @@ -400,9 +394,6 @@

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();
Expand All @@ -416,11 +407,6 @@
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;
Expand Down
82 changes: 8 additions & 74 deletions src/system_tray.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,6 @@
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();
Expand Down Expand Up @@ -207,16 +202,12 @@

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() {
Expand Down Expand Up @@ -319,63 +310,22 @@
// 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);

// 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;
}
}
auto tray_thread = std::thread(tray_thread_worker);

Check warning on line 324 in src/system_tray.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace this use of "std::thread" with "std::jthread".

See more on https://sonarcloud.io/project/issues?id=LizardByte_Sunshine&issues=AZrMSaxLwp9VPPRr28HG&open=AZrMSaxLwp9VPPRr28HG&pullRequest=4457

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();

Check warning on line 328 in src/system_tray.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Consider giving the thread a bigger scope instead of detaching it.

See more on https://sonarcloud.io/project/issues?id=LizardByte_Sunshine&issues=AZrMSaxLwp9VPPRr28HF&open=AZrMSaxLwp9VPPRr28HF&pullRequest=4457

BOOST_LOG(info) << "System tray thread initialized successfully"sv;
return 0;
Expand All @@ -385,21 +335,5 @@
}
}

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
6 changes: 0 additions & 6 deletions src/system_tray.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion third-party/tray
Loading