[common] remove DetachedTasks object usage

Signed-off-by: lizzie <lizzie@eden-emu.dev>
This commit is contained in:
lizzie 2026-06-14 22:27:18 -04:00
parent 73918d23d5
commit d46fcf5134
10 changed files with 10 additions and 112 deletions

View file

@ -39,7 +39,6 @@
#include "common/android/multiplayer/multiplayer.h"
#include "common/android/android_common.h"
#include "common/android/id_cache.h"
#include "common/detached_tasks.h"
#include "common/dynamic_library.h"
#include "common/fs/path_util.h"
#include "common/logging.h"
@ -352,7 +351,6 @@ void EmulationSession::ShutdownEmulation() {
if (m_load_result == Core::SystemResultStatus::Success) {
m_system.DetachDebugger();
m_system.ShutdownMainProcess();
m_detached_tasks.WaitForAllTasks();
m_load_result = Core::SystemResultStatus::ErrorNotInitialized;
m_window.reset();
OnEmulationStopped(Core::SystemResultStatus::Success);

View file

@ -6,7 +6,6 @@
#include <android/native_window_jni.h>
#include "common/android/applets/software_keyboard.h"
#include "common/detached_tasks.h"
#include "core/core.h"
#include "core/file_sys/registered_cache.h"
#include "core/hle/service/acc/profile_manager.h"
@ -75,7 +74,6 @@ private:
// Core emulation
Core::System m_system;
InputCommon::InputSubsystem m_input_subsystem;
Common::DetachedTasks m_detached_tasks;
Core::PerfStatsResults m_perf_stats{};
int m_shaders_building{0};
std::shared_ptr<FileSys::VfsFilesystem> m_vfs;

View file

@ -40,8 +40,6 @@ add_library(
container_hash.h
demangle.cpp
demangle.h
detached_tasks.cpp
detached_tasks.h
device_power_state.cpp
device_power_state.h
div_ceil.h

View file

@ -1,41 +0,0 @@
// SPDX-FileCopyrightText: 2018 Citra Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <thread>
#include "common/assert.h"
#include "common/detached_tasks.h"
namespace Common {
DetachedTasks* DetachedTasks::instance = nullptr;
DetachedTasks::DetachedTasks() {
ASSERT(instance == nullptr);
instance = this;
}
void DetachedTasks::WaitForAllTasks() {
std::unique_lock lock{mutex};
cv.wait(lock, [this]() { return count == 0; });
}
DetachedTasks::~DetachedTasks() {
WaitForAllTasks();
std::unique_lock lock{mutex};
ASSERT(count == 0);
instance = nullptr;
}
void DetachedTasks::AddTask(std::function<void()> task) {
std::unique_lock lock{instance->mutex};
++instance->count;
std::thread([task_{std::move(task)}]() {
task_();
std::unique_lock thread_lock{instance->mutex};
--instance->count;
std::notify_all_at_thread_exit(instance->cv, std::move(thread_lock));
}).detach();
}
} // namespace Common

View file

@ -1,39 +0,0 @@
// SPDX-FileCopyrightText: 2018 Citra Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <condition_variable>
#include <functional>
namespace Common {
/**
* A background manager which ensures that all detached task is finished before program exits.
*
* Some tasks, telemetry submission for example, prefer executing asynchronously and don't care
* about the result. These tasks are suitable for std::thread::detach(). However, this is unsafe if
* the task is launched just before the program exits (which is a common case for telemetry), so we
* need to block on these tasks on program exit.
*
* To make detached task safe, a single DetachedTasks object should be placed in the main(), and
* call WaitForAllTasks() after all program execution but before global/static variable destruction.
* Any potentially unsafe detached task should be executed via DetachedTasks::AddTask.
*/
class DetachedTasks {
public:
DetachedTasks();
~DetachedTasks();
void WaitForAllTasks();
static void AddTask(std::function<void()> task);
private:
static DetachedTasks* instance;
std::condition_variable cv;
std::mutex mutex;
int count = 0;
};
} // namespace Common

View file

@ -24,7 +24,6 @@
#include <openssl/evp.h>
#include "common/common_types.h"
#include "common/detached_tasks.h"
#include "common/fs/file.h"
#include "common/fs/fs.h"
#include "common/fs/path_util.h"
@ -172,9 +171,7 @@ static void SaveBanList(const Network::Room::BanList& ban_list, const std::strin
}
/// Application entry point
void LaunchRoom(int argc, char** argv, bool called_by_option)
{
Common::DetachedTasks detached_tasks;
void LaunchRoom(int argc, char** argv, bool called_by_option) {
int option_index = 0;
char* endarg;
@ -393,6 +390,5 @@ void LaunchRoom(int argc, char** argv, bool called_by_option)
room->Destroy();
}
Network::Shutdown();
detached_tasks.WaitForAllTasks();
std::exit(0);
}

View file

@ -6,7 +6,6 @@
#include <future>
#include <nlohmann/json.hpp>
#include "common/detached_tasks.h"
#include "common/logging.h"
#include "web_service/announce_room_json.h"
#include "web_service/web_backend.h"
@ -136,13 +135,13 @@ AnnounceMultiplayerRoom::RoomList RoomJson::GetRoomList() {
void RoomJson::Delete() {
if (room_id.empty()) {
LOG_ERROR(WebService, "Room must be registered to be deleted");
return;
} else {
// This jthread won't be destroyed until after the dtor has been ran
// Once the thread finishes it will stay resident on the vector -- destroyed and freed by dtor()
detached_tasks.emplace_back([](std::stop_token stop_token, RoomJson& this_) {
this_.client.DeleteJson(fmt::format("/lobby/{}", this_.room_id), "", false);
}, *this);
}
Common::DetachedTasks::AddTask([host_{this->host}, username_{this->username},
token_{this->token}, room_id_{this->room_id}]() {
// create a new client here because the this->client might be destroyed.
Client{host_, username_, token_}.DeleteJson(fmt::format("/lobby/{}", room_id_), "", false);
});
}
} // namespace WebService

View file

@ -30,6 +30,7 @@ public:
void Delete() override;
private:
std::vector<std::jthread> detached_tasks;
AnnounceMultiplayerRoom::Room room;
Client client;
std::string host;

View file

@ -8,9 +8,6 @@
#include <cstring>
#include "dedicated_room/yuzu_room.h"
#endif
#include <common/detached_tasks.h>
#ifdef __unix__
#include "qt_common/gui_settings.h"
#endif
@ -104,8 +101,6 @@ int main(int argc, char* argv[]) {
Breakpad::InstallCrashHandler();
#endif
Common::DetachedTasks detached_tasks;
// Init settings params
QCoreApplication::setOrganizationName(QStringLiteral("eden"));
QCoreApplication::setApplicationName(QStringLiteral("eden"));
@ -193,10 +188,6 @@ int main(int argc, char* argv[]) {
// After settings have been loaded by GMainWindow, apply the filter
main_window.show();
app.connect(&app, &QGuiApplication::applicationStateChanged, &main_window,
&MainWindow::OnAppFocusStateChanged);
int result = app.exec();
detached_tasks.WaitForAllTasks();
return result;
app.connect(&app, &QGuiApplication::applicationStateChanged, &main_window, &MainWindow::OnAppFocusStateChanged);
return app.exec();
}

View file

@ -11,7 +11,6 @@
#include <fmt/ostream.h>
#include "common/detached_tasks.h"
#include "common/logging.h"
#include "common/scm_rev.h"
#include "common/settings.h"
@ -187,7 +186,6 @@ int main(int argc, char** argv) {
Common::Log::Initialize();
Common::Log::SetColorConsoleBackendEnabled(true);
Common::Log::Start();
Common::DetachedTasks detached_tasks;
int option_index = 0;
#ifdef _WIN32
@ -452,7 +450,6 @@ int main(int argc, char** argv) {
system.DetachDebugger();
void(system.Pause());
system.ShutdownMainProcess();
detached_tasks.WaitForAllTasks();
return 0;
}