Compare commits
2 Commits
master
...
mainline-0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
171412d171 | ||
|
|
7eeee774c6 |
@@ -11,6 +11,7 @@
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include "common/common_types.h"
|
||||
#include "common/polyfill_thread.h"
|
||||
|
||||
namespace Common {
|
||||
|
||||
@@ -69,7 +70,7 @@ public:
|
||||
explicit Barrier(std::size_t count_) : count(count_) {}
|
||||
|
||||
/// Blocks until all "count" threads have called Sync()
|
||||
void Sync() {
|
||||
bool Sync(std::stop_token token = {}) {
|
||||
std::unique_lock lk{mutex};
|
||||
const std::size_t current_generation = generation;
|
||||
|
||||
@@ -77,14 +78,16 @@ public:
|
||||
generation++;
|
||||
waiting = 0;
|
||||
condvar.notify_all();
|
||||
return true;
|
||||
} else {
|
||||
condvar.wait(lk,
|
||||
[this, current_generation] { return current_generation != generation; });
|
||||
CondvarWait(condvar, lk, token,
|
||||
[this, current_generation] { return current_generation != generation; });
|
||||
return !token.stop_requested();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::condition_variable condvar;
|
||||
std::condition_variable_any condvar;
|
||||
std::mutex mutex;
|
||||
std::size_t count;
|
||||
std::size_t waiting = 0;
|
||||
|
||||
@@ -389,7 +389,9 @@ struct System::Impl {
|
||||
kernel.ShutdownCores();
|
||||
cpu_manager.Shutdown();
|
||||
debugger.reset();
|
||||
services->KillNVNFlinger();
|
||||
if (services) {
|
||||
services->KillNVNFlinger();
|
||||
}
|
||||
kernel.CloseServices();
|
||||
services.reset();
|
||||
service_manager.reset();
|
||||
|
||||
@@ -20,23 +20,20 @@ namespace Core {
|
||||
CpuManager::CpuManager(System& system_) : system{system_} {}
|
||||
CpuManager::~CpuManager() = default;
|
||||
|
||||
void CpuManager::ThreadStart(std::stop_token stop_token, CpuManager& cpu_manager,
|
||||
std::size_t core) {
|
||||
cpu_manager.RunThread(core);
|
||||
}
|
||||
|
||||
void CpuManager::Initialize() {
|
||||
num_cores = is_multicore ? Core::Hardware::NUM_CPU_CORES : 1;
|
||||
gpu_barrier = std::make_unique<Common::Barrier>(num_cores + 1);
|
||||
|
||||
for (std::size_t core = 0; core < num_cores; core++) {
|
||||
core_data[core].host_thread = std::jthread(ThreadStart, std::ref(*this), core);
|
||||
core_data[core].host_thread =
|
||||
std::jthread([this, core](std::stop_token token) { RunThread(token, core); });
|
||||
}
|
||||
}
|
||||
|
||||
void CpuManager::Shutdown() {
|
||||
for (std::size_t core = 0; core < num_cores; core++) {
|
||||
if (core_data[core].host_thread.joinable()) {
|
||||
core_data[core].host_thread.request_stop();
|
||||
core_data[core].host_thread.join();
|
||||
}
|
||||
}
|
||||
@@ -184,7 +181,7 @@ void CpuManager::ShutdownThread() {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
void CpuManager::RunThread(std::size_t core) {
|
||||
void CpuManager::RunThread(std::stop_token token, std::size_t core) {
|
||||
/// Initialization
|
||||
system.RegisterCoreThread(core);
|
||||
std::string name;
|
||||
@@ -206,7 +203,9 @@ void CpuManager::RunThread(std::size_t core) {
|
||||
});
|
||||
|
||||
// Running
|
||||
gpu_barrier->Sync();
|
||||
if (!gpu_barrier->Sync(token)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_async_gpu && !is_multicore) {
|
||||
system.GPU().ObtainContext();
|
||||
|
||||
@@ -81,12 +81,10 @@ private:
|
||||
void SingleCoreRunGuestThread();
|
||||
void SingleCoreRunIdleThread();
|
||||
|
||||
static void ThreadStart(std::stop_token stop_token, CpuManager& cpu_manager, std::size_t core);
|
||||
|
||||
void GuestActivate();
|
||||
void HandleInterrupt();
|
||||
void ShutdownThread();
|
||||
void RunThread(std::size_t core);
|
||||
void RunThread(std::stop_token stop_token, std::size_t core);
|
||||
|
||||
struct CoreData {
|
||||
std::shared_ptr<Common::Fiber> host_context;
|
||||
|
||||
@@ -104,12 +104,16 @@ struct KernelCore::Impl {
|
||||
}
|
||||
|
||||
void CloseCurrentProcess() {
|
||||
(*current_process).Finalize();
|
||||
// current_process->Close();
|
||||
// TODO: The current process should be destroyed based on accurate ref counting after
|
||||
KProcess* old_process = current_process.exchange(nullptr);
|
||||
if (old_process == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
// old_process->Close();
|
||||
// TODO: The process should be destroyed based on accurate ref counting after
|
||||
// calling Close(). Adding a manual Destroy() call instead to avoid a memory leak.
|
||||
(*current_process).Destroy();
|
||||
current_process = nullptr;
|
||||
old_process->Finalize();
|
||||
old_process->Destroy();
|
||||
}
|
||||
|
||||
void Shutdown() {
|
||||
|
||||
@@ -487,7 +487,7 @@ void LANDiscovery::ReceivePacket(const Network::LDNPacket& packet) {
|
||||
std::scoped_lock lock{packet_mutex};
|
||||
switch (packet.type) {
|
||||
case Network::LDNPacketType::Scan: {
|
||||
LOG_INFO(Frontend, "Scan packet received!");
|
||||
LOG_DEBUG(Frontend, "Scan packet received!");
|
||||
if (state == State::AccessPointCreated) {
|
||||
// Reply to the sender
|
||||
SendPacket(Network::LDNPacketType::ScanResp, network_info, packet.local_ip);
|
||||
@@ -495,7 +495,7 @@ void LANDiscovery::ReceivePacket(const Network::LDNPacket& packet) {
|
||||
break;
|
||||
}
|
||||
case Network::LDNPacketType::ScanResp: {
|
||||
LOG_INFO(Frontend, "ScanResp packet received!");
|
||||
LOG_DEBUG(Frontend, "ScanResp packet received!");
|
||||
|
||||
NetworkInfo info{};
|
||||
std::memcpy(&info, packet.data.data(), sizeof(NetworkInfo));
|
||||
@@ -611,13 +611,6 @@ MacAddress LANDiscovery::GetFakeMac() const {
|
||||
|
||||
Result LANDiscovery::GetNodeInfo(NodeInfo& node, const UserConfig& userConfig,
|
||||
u16 localCommunicationVersion) {
|
||||
const auto network_interface = Network::GetSelectedNetworkInterface();
|
||||
|
||||
if (!network_interface) {
|
||||
LOG_ERROR(Service_LDN, "No network interface available");
|
||||
return ResultNoIpAddress;
|
||||
}
|
||||
|
||||
node.mac_address = GetFakeMac();
|
||||
node.is_connected = 1;
|
||||
std::memcpy(node.user_name.data(), userConfig.user_name.data(), UserNameBytesMax + 1);
|
||||
|
||||
@@ -150,7 +150,7 @@ public:
|
||||
}
|
||||
|
||||
~IUserLocalCommunicationService() {
|
||||
if (is_initialized) {
|
||||
if (is_network_available) {
|
||||
if (auto room_member = room_network.GetRoomMember().lock()) {
|
||||
room_member->Unbind(ldn_packet_received);
|
||||
}
|
||||
@@ -193,7 +193,7 @@ public:
|
||||
NetworkInfo network_info{};
|
||||
const auto rc = lan_discovery.GetNetworkInfo(network_info);
|
||||
if (rc.IsError()) {
|
||||
LOG_ERROR(Service_LDN, "NetworkInfo is not valid {}", rc.raw);
|
||||
LOG_DEBUG(Service_LDN, "NetworkInfo is not valid {}", rc.raw);
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(rc);
|
||||
return;
|
||||
@@ -205,6 +205,14 @@ public:
|
||||
}
|
||||
|
||||
void GetIpv4Address(Kernel::HLERequestContext& ctx) {
|
||||
if (!is_network_available) {
|
||||
IPC::ResponseBuilder rb{ctx, 4};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushRaw(Ipv4Address{127, 0, 0, 1});
|
||||
rb.PushRaw(Ipv4Address{255, 255, 255, 0});
|
||||
return;
|
||||
}
|
||||
|
||||
const auto network_interface = Network::GetSelectedNetworkInterface();
|
||||
|
||||
if (!network_interface) {
|
||||
@@ -342,6 +350,13 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_network_available) {
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.Push(0);
|
||||
return;
|
||||
}
|
||||
|
||||
u16 count = 0;
|
||||
std::vector<NetworkInfo> network_infos(network_info_size);
|
||||
Result rc = lan_discovery.Scan(network_infos, count, scan_filter);
|
||||
@@ -488,18 +503,18 @@ public:
|
||||
}
|
||||
|
||||
void Initialize(Kernel::HLERequestContext& ctx) {
|
||||
const auto rc = InitializeImpl(ctx);
|
||||
if (rc.IsError()) {
|
||||
LOG_ERROR(Service_LDN, "Network isn't initialized, rc={}", rc.raw);
|
||||
}
|
||||
InitializeImpl(ctx);
|
||||
|
||||
// Initialize always returns success
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(rc);
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
void Finalize(Kernel::HLERequestContext& ctx) {
|
||||
if (auto room_member = room_network.GetRoomMember().lock()) {
|
||||
room_member->Unbind(ldn_packet_received);
|
||||
if (is_network_available) {
|
||||
if (auto room_member = room_network.GetRoomMember().lock()) {
|
||||
room_member->Unbind(ldn_packet_received);
|
||||
}
|
||||
}
|
||||
|
||||
is_initialized = false;
|
||||
@@ -519,22 +534,25 @@ public:
|
||||
}
|
||||
|
||||
Result InitializeImpl(Kernel::HLERequestContext& ctx) {
|
||||
lan_discovery.Initialize([&]() { OnEventFired(); });
|
||||
is_initialized = true;
|
||||
is_network_available = false;
|
||||
|
||||
const auto network_interface = Network::GetSelectedNetworkInterface();
|
||||
if (!network_interface) {
|
||||
LOG_ERROR(Service_LDN, "No network interface is set");
|
||||
return ResultAirplaneModeEnabled;
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
if (auto room_member = room_network.GetRoomMember().lock()) {
|
||||
ldn_packet_received = room_member->BindOnLdnPacketReceived(
|
||||
[this](const Network::LDNPacket& packet) { OnLDNPacketReceived(packet); });
|
||||
is_network_available = true;
|
||||
} else {
|
||||
LOG_ERROR(Service_LDN, "Couldn't bind callback!");
|
||||
return ResultAirplaneModeEnabled;
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
lan_discovery.Initialize([&]() { OnEventFired(); });
|
||||
is_initialized = true;
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
@@ -547,6 +565,7 @@ public:
|
||||
Network::RoomMember::CallbackHandle<Network::LDNPacket> ldn_packet_received;
|
||||
|
||||
bool is_initialized{};
|
||||
bool is_network_available{};
|
||||
};
|
||||
|
||||
class LDNS final : public ServiceFramework<LDNS> {
|
||||
|
||||
@@ -200,7 +200,7 @@ std::optional<NetworkInterface> GetSelectedNetworkInterface() {
|
||||
});
|
||||
|
||||
if (res == network_interfaces.end()) {
|
||||
LOG_ERROR(Network, "Couldn't find selected interface \"{}\"", selected_network_interface);
|
||||
LOG_DEBUG(Network, "Couldn't find selected interface \"{}\"", selected_network_interface);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
|
||||
@@ -946,7 +946,6 @@ void GMainWindow::InitializeWidgets() {
|
||||
statusBar()->addPermanentWidget(label);
|
||||
}
|
||||
|
||||
// TODO (flTobi): Add the widget when multiplayer is fully implemented
|
||||
statusBar()->addPermanentWidget(multiplayer_state->GetStatusText(), 0);
|
||||
statusBar()->addPermanentWidget(multiplayer_state->GetStatusIcon(), 0);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user