From afb6dd7747adf3787eb3b0f8b3d11efaff7c894e Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 6 Nov 2017 14:09:56 -0500 Subject: [PATCH] HLE/SRV: Don't return the port handle if it isn't available when calling GetServiceHandle. This was incorrect behavior that somehow found its way to 3dbrew. The correct behavior is to sleep until the port becomes available again and then return a session to it. This is currently unimplemented due to the inability to put a guest thread to sleep during HLE requests. The correct behavior was reverse engineered by TuxSH a while ago but we never corrected the code in citra. --- src/core/hle/service/sm/srv.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/core/hle/service/sm/srv.cpp b/src/core/hle/service/sm/srv.cpp index 4c3dd69ce..d05cec5b3 100644 --- a/src/core/hle/service/sm/srv.cpp +++ b/src/core/hle/service/sm/srv.cpp @@ -87,7 +87,7 @@ void SRV::GetServiceHandle(Kernel::HLERequestContext& ctx) { size_t name_len = rp.Pop(); u32 flags = rp.Pop(); - bool return_port_on_failure = (flags & 1) == 0; + bool wait_until_available = (flags & 1) == 0; if (name_len > Service::kMaxPortSize) { IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); @@ -115,12 +115,10 @@ void SRV::GetServiceHandle(Kernel::HLERequestContext& ctx) { IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); rb.Push(session.Code()); rb.PushObjects(std::move(session).Unwrap()); - } else if (session.Code() == Kernel::ERR_MAX_CONNECTIONS_REACHED && return_port_on_failure) { - LOG_WARNING(Service_SRV, "called service=%s -> ERR_MAX_CONNECTIONS_REACHED, *port*=%u", - name.c_str(), (*client_port)->GetObjectId()); - IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); - rb.Push(ERR_MAX_CONNECTIONS_REACHED); - rb.PushObjects(std::move(client_port).Unwrap()); + } else if (session.Code() == Kernel::ERR_MAX_CONNECTIONS_REACHED && wait_until_available) { + LOG_WARNING(Service_SRV, "called service=%s -> ERR_MAX_CONNECTIONS_REACHED", name.c_str()); + // TODO(Subv): Put the caller guest thread to sleep until this port becomes available again. + UNIMPLEMENTED_MSG("Unimplemented wait until port %s is available.", name.c_str()); } else { LOG_ERROR(Service_SRV, "called service=%s -> error 0x%08X", name.c_str(), session.Code().raw);