early-access version 3837

This commit is contained in:
pineappleEA
2023-08-27 02:56:33 +02:00
parent d07529eada
commit c807f0cfc8
17 changed files with 252 additions and 94 deletions

View File

@@ -273,7 +273,8 @@ struct System::Impl {
time_manager.Initialize();
is_powered_on = true;
exit_lock = false;
exit_locked = false;
exit_requested = false;
microprofile_cpu[0] = MICROPROFILE_TOKEN(ARM_CPU0);
microprofile_cpu[1] = MICROPROFILE_TOKEN(ARM_CPU1);
@@ -398,12 +399,14 @@ struct System::Impl {
}
is_powered_on = false;
exit_lock = false;
exit_locked = false;
exit_requested = false;
if (gpu_core != nullptr) {
gpu_core->NotifyShutdown();
}
Network::CancelPendingSocketOperations();
kernel.SuspendApplication(true);
if (services) {
services->KillNVNFlinger();
@@ -425,6 +428,7 @@ struct System::Impl {
debugger.reset();
kernel.Shutdown();
memory.Reset();
Network::RestartSocketOperations();
if (auto room_member = room_network.GetRoomMember().lock()) {
Network::GameInfo game_info{};
@@ -507,7 +511,8 @@ struct System::Impl {
CpuManager cpu_manager;
std::atomic_bool is_powered_on{};
bool exit_lock = false;
bool exit_locked = false;
bool exit_requested = false;
bool nvdec_active{};
@@ -943,12 +948,20 @@ const Service::Time::TimeManager& System::GetTimeManager() const {
return impl->time_manager;
}
void System::SetExitLock(bool locked) {
impl->exit_lock = locked;
void System::SetExitLocked(bool locked) {
impl->exit_locked = locked;
}
bool System::GetExitLock() const {
return impl->exit_lock;
bool System::GetExitLocked() const {
return impl->exit_locked;
}
void System::SetExitRequested(bool requested) {
impl->exit_requested = requested;
}
bool System::GetExitRequested() const {
return impl->exit_requested;
}
void System::SetApplicationProcessBuildID(const CurrentBuildProcessID& id) {

View File

@@ -412,8 +412,11 @@ public:
/// Gets an immutable reference to the Room Network.
[[nodiscard]] const Network::RoomNetwork& GetRoomNetwork() const;
void SetExitLock(bool locked);
[[nodiscard]] bool GetExitLock() const;
void SetExitLocked(bool locked);
bool GetExitLocked() const;
void SetExitRequested(bool requested);
bool GetExitRequested() const;
void SetApplicationProcessBuildID(const CurrentBuildProcessID& id);
[[nodiscard]] const CurrentBuildProcessID& GetApplicationProcessBuildID() const;

View File

@@ -341,7 +341,7 @@ void ISelfController::Exit(HLERequestContext& ctx) {
void ISelfController::LockExit(HLERequestContext& ctx) {
LOG_DEBUG(Service_AM, "called");
system.SetExitLock(true);
system.SetExitLocked(true);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
@@ -350,10 +350,14 @@ void ISelfController::LockExit(HLERequestContext& ctx) {
void ISelfController::UnlockExit(HLERequestContext& ctx) {
LOG_DEBUG(Service_AM, "called");
system.SetExitLock(false);
system.SetExitLocked(false);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
if (system.GetExitRequested()) {
system.Exit();
}
}
void ISelfController::EnterFatalSection(HLERequestContext& ctx) {

View File

@@ -48,15 +48,32 @@ enum class CallType {
using socklen_t = int;
SOCKET interrupt_socket = static_cast<SOCKET>(-1);
void InterruptSocketOperations() {
closesocket(interrupt_socket);
}
void AcknowledgeInterrupt() {
interrupt_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
}
void Initialize() {
WSADATA wsa_data;
(void)WSAStartup(MAKEWORD(2, 2), &wsa_data);
AcknowledgeInterrupt();
}
void Finalize() {
InterruptSocketOperations();
WSACleanup();
}
SOCKET GetInterruptSocket() {
return interrupt_socket;
}
sockaddr TranslateFromSockAddrIn(SockAddrIn input) {
sockaddr_in result;
@@ -157,9 +174,39 @@ constexpr int SD_RECEIVE = SHUT_RD;
constexpr int SD_SEND = SHUT_WR;
constexpr int SD_BOTH = SHUT_RDWR;
void Initialize() {}
int interrupt_pipe_fd[2] = {-1, -1};
void Finalize() {}
void Initialize() {
if (pipe(interrupt_pipe_fd) != 0) {
LOG_ERROR(Network, "Failed to create interrupt pipe!");
}
int flags = fcntl(interrupt_pipe_fd[0], F_GETFL);
ASSERT_MSG(fcntl(interrupt_pipe_fd[0], F_SETFL, flags | O_NONBLOCK) == 0,
"Failed to set nonblocking state for interrupt pipe");
}
void Finalize() {
if (interrupt_pipe_fd[0] >= 0) {
close(interrupt_pipe_fd[0]);
}
if (interrupt_pipe_fd[1] >= 0) {
close(interrupt_pipe_fd[1]);
}
}
void InterruptSocketOperations() {
u8 value = 0;
ASSERT(write(interrupt_pipe_fd[1], &value, sizeof(value)) == 1);
}
void AcknowledgeInterrupt() {
u8 value = 0;
read(interrupt_pipe_fd[0], &value, sizeof(value));
}
SOCKET GetInterruptSocket() {
return interrupt_pipe_fd[0];
}
sockaddr TranslateFromSockAddrIn(SockAddrIn input) {
sockaddr_in result;
@@ -490,6 +537,14 @@ NetworkInstance::~NetworkInstance() {
Finalize();
}
void CancelPendingSocketOperations() {
InterruptSocketOperations();
}
void RestartSocketOperations() {
AcknowledgeInterrupt();
}
std::optional<IPv4Address> GetHostIPv4Address() {
const auto network_interface = Network::GetSelectedNetworkInterface();
if (!network_interface.has_value()) {
@@ -560,7 +615,14 @@ std::pair<s32, Errno> Poll(std::vector<PollFD>& pollfds, s32 timeout) {
return result;
});
const int result = WSAPoll(host_pollfds.data(), static_cast<ULONG>(num), timeout);
host_pollfds.push_back(WSAPOLLFD{
.fd = GetInterruptSocket(),
.events = POLLIN,
.revents = 0,
});
const int result =
WSAPoll(host_pollfds.data(), static_cast<ULONG>(host_pollfds.size()), timeout);
if (result == 0) {
ASSERT(std::all_of(host_pollfds.begin(), host_pollfds.end(),
[](WSAPOLLFD fd) { return fd.revents == 0; }));
@@ -627,6 +689,24 @@ Errno Socket::Initialize(Domain domain, Type type, Protocol protocol) {
std::pair<SocketBase::AcceptResult, Errno> Socket::Accept() {
sockaddr_in addr;
socklen_t addrlen = sizeof(addr);
std::vector<WSAPOLLFD> host_pollfds{
WSAPOLLFD{fd, POLLIN, 0},
WSAPOLLFD{GetInterruptSocket(), POLLIN, 0},
};
while (true) {
const int pollres =
WSAPoll(host_pollfds.data(), static_cast<ULONG>(host_pollfds.size()), -1);
if (host_pollfds[1].revents != 0) {
// Interrupt signaled before a client could be accepted, break
return {AcceptResult{}, Errno::AGAIN};
}
if (pollres > 0) {
break;
}
}
const SOCKET new_socket = accept(fd, reinterpret_cast<sockaddr*>(&addr), &addrlen);
if (new_socket == INVALID_SOCKET) {

View File

@@ -96,6 +96,9 @@ public:
~NetworkInstance();
};
void CancelPendingSocketOperations();
void RestartSocketOperations();
#ifdef _WIN32
constexpr IPv4Address TranslateIPv4(in_addr addr) {
auto& bytes = addr.S_un.S_un_b;