diff --git a/Source/Core/Core/IOS/Network/IP/Top.cpp b/Source/Core/Core/IOS/Network/IP/Top.cpp index 24987f6ad9..4eb2455c19 100644 --- a/Source/Core/Core/IOS/Network/IP/Top.cpp +++ b/Source/Core/Core/IOS/Network/IP/Top.cpp @@ -64,6 +64,13 @@ enum SOResultCode : s32 NetIPTopDevice::NetIPTopDevice(Kernel& ios, const std::string& device_name) : Device(ios, device_name) { + m_work_queue.Reset([this](AsyncTask task) { + const IPCReply reply = task.handler(); + { + std::lock_guard lg(m_async_reply_lock); + m_async_replies.emplace(AsyncReply{task.request, reply.return_value}); + } + }); } void NetIPTopDevice::DoState(PointerWrap& p) @@ -319,7 +326,7 @@ std::optional NetIPTopDevice::IOCtl(const IOCtlRequest& request) case IOCTL_SO_POLL: return HandlePollRequest(request); case IOCTL_SO_GETHOSTBYNAME: - return HandleGetHostByNameRequest(request); + return LaunchAsyncTask(&NetIPTopDevice::HandleGetHostByNameRequest, request); case IOCTL_SO_ICMPCANCEL: return HandleICMPCancelRequest(request); default: @@ -341,7 +348,7 @@ std::optional NetIPTopDevice::IOCtlV(const IOCtlVRequest& request) case IOCTLV_SO_RECVFROM: return HandleRecvFromRequest(request); case IOCTLV_SO_GETADDRINFO: - return HandleGetAddressInfoRequest(request); + return LaunchAsyncTask(&NetIPTopDevice::HandleGetAddressInfoRequest, request); case IOCTLV_SO_ICMPPING: return HandleICMPPingRequest(request); default: @@ -354,6 +361,15 @@ std::optional NetIPTopDevice::IOCtlV(const IOCtlVRequest& request) void NetIPTopDevice::Update() { + { + std::lock_guard lg(m_async_reply_lock); + while (!m_async_replies.empty()) + { + const auto& reply = m_async_replies.front(); + GetIOS()->EnqueueIPCReply(reply.request, reply.return_value); + m_async_replies.pop(); + } + } WiiSockMan::GetInstance().Update(); } diff --git a/Source/Core/Core/IOS/Network/IP/Top.h b/Source/Core/Core/IOS/Network/IP/Top.h index 94cd5d7628..cc41180860 100644 --- a/Source/Core/Core/IOS/Network/IP/Top.h +++ b/Source/Core/Core/IOS/Network/IP/Top.h @@ -3,10 +3,12 @@ #pragma once +#include #include #include "Common/CommonTypes.h" #include "Common/SocketContext.h" +#include "Common/WorkQueueThread.h" #include "Core/IOS/Device.h" #ifdef _WIN32 @@ -73,6 +75,25 @@ public: void Update() override; private: + struct AsyncTask + { + IOS::HLE::Request request; + std::function handler; + }; + + struct AsyncReply + { + IOS::HLE::Request request; + s32 return_value; + }; + + template + std::optional LaunchAsyncTask(Method method, const Request& request) + { + m_work_queue.EmplaceItem(AsyncTask{request, std::bind(method, this, request)}); + return std::nullopt; + } + IPCReply HandleInitInterfaceRequest(const IOCtlRequest& request); IPCReply HandleSocketRequest(const IOCtlRequest& request); IPCReply HandleICMPSocketRequest(const IOCtlRequest& request); @@ -99,5 +120,8 @@ private: IPCReply HandleICMPPingRequest(const IOCtlVRequest& request); Common::SocketContext m_socket_context; + Common::WorkQueueThread m_work_queue; + std::mutex m_async_reply_lock; + std::queue m_async_replies; }; } // namespace IOS::HLE