Просмотр исходного кода

Return an error code when connecting to a saturated port.

The error code was taken from the 3DS kernel.
Subv 9 лет назад
Родитель
Сommit
c93c5a72bb

+ 9 - 2
src/core/hle/kernel/client_port.cpp

@@ -14,7 +14,14 @@ namespace Kernel {
 ClientPort::ClientPort() {}
 ClientPort::ClientPort() {}
 ClientPort::~ClientPort() {}
 ClientPort::~ClientPort() {}
 
 
-SharedPtr<ClientSession> ClientPort::Connect() {
+ResultVal<SharedPtr<ClientSession>> ClientPort::Connect() {
+    if (active_sessions >= max_sessions) {
+        return ResultCode(ErrorDescription::MaxConnectionsReached,
+                          ErrorModule::OS, ErrorSummary::WouldBlock,
+                          ErrorLevel::Temporary);
+    }
+    active_sessions++;
+
     // Create a new session pair, let the created sessions inherit the parent port's HLE handler.
     // Create a new session pair, let the created sessions inherit the parent port's HLE handler.
     auto sessions = ServerSession::CreateSessionPair(server_port->GetName(), server_port->hle_handler);
     auto sessions = ServerSession::CreateSessionPair(server_port->GetName(), server_port->hle_handler);
     auto client_session = std::get<SharedPtr<ClientSession>>(sessions);
     auto client_session = std::get<SharedPtr<ClientSession>>(sessions);
@@ -25,7 +32,7 @@ SharedPtr<ClientSession> ClientPort::Connect() {
     // Wake the threads waiting on the ServerPort
     // Wake the threads waiting on the ServerPort
     server_port->WakeupAllWaitingThreads();
     server_port->WakeupAllWaitingThreads();
 
 
-    return std::move(client_session);
+    return MakeResult<SharedPtr<ClientSession>>(std::move(client_session));
 }
 }
 
 
 } // namespace
 } // namespace

+ 2 - 2
src/core/hle/kernel/client_port.h

@@ -31,9 +31,9 @@ public:
     /**
     /**
      * Creates a new Session pair, adds the created ServerSession to the associated ServerPort's list of pending sessions,
      * Creates a new Session pair, adds the created ServerSession to the associated ServerPort's list of pending sessions,
      * and signals the ServerPort, causing any threads waiting on it to awake.
      * and signals the ServerPort, causing any threads waiting on it to awake.
-     * @returns ClientSession The client endpoint of the created Session pair.
+     * @returns ClientSession The client endpoint of the created Session pair, or error code.
      */
      */
-    SharedPtr<ClientSession> Connect();
+    ResultVal<SharedPtr<ClientSession>> Connect();
 
 
     SharedPtr<ServerPort> server_port; ///< ServerPort associated with this client port.
     SharedPtr<ServerPort> server_port; ///< ServerPort associated with this client port.
     u32 max_sessions;    ///< Maximum number of simultaneous sessions the port can have
     u32 max_sessions;    ///< Maximum number of simultaneous sessions the port can have

+ 1 - 0
src/core/hle/result.h

@@ -18,6 +18,7 @@ enum class ErrorDescription : u32 {
     Success = 0,
     Success = 0,
     WrongPermission = 46,
     WrongPermission = 46,
     OS_InvalidBufferDescriptor = 48,
     OS_InvalidBufferDescriptor = 48,
+    MaxConnectionsReached = 52,
     WrongAddress = 53,
     WrongAddress = 53,
     FS_ArchiveNotMounted = 101,
     FS_ArchiveNotMounted = 101,
     FS_FileNotFound = 112,
     FS_FileNotFound = 112,

+ 6 - 2
src/core/hle/service/srv.cpp

@@ -93,8 +93,12 @@ static void GetServiceHandle(Service::Interface* self) {
         // Connect to the port and retrieve the client endpoint of the connection Session.
         // Connect to the port and retrieve the client endpoint of the connection Session.
         auto client_session = client_port->Connect();
         auto client_session = client_port->Connect();
 
 
-        // Return the client session
-        cmd_buff[3] = Kernel::g_handle_table.Create(client_session).MoveFrom();
+        res = client_session.Code();
+
+        if (client_session.Succeeded()) {
+            // Return the client session
+            cmd_buff[3] = Kernel::g_handle_table.Create(*client_session).MoveFrom();
+        }
         LOG_TRACE(Service_SRV, "called port=%s, handle=0x%08X", port_name.c_str(), cmd_buff[3]);
         LOG_TRACE(Service_SRV, "called port=%s, handle=0x%08X", port_name.c_str(), cmd_buff[3]);
     } else {
     } else {
         LOG_ERROR(Service_SRV, "(UNIMPLEMENTED) called port=%s", port_name.c_str());
         LOG_ERROR(Service_SRV, "(UNIMPLEMENTED) called port=%s", port_name.c_str());

+ 2 - 1
src/core/hle/svc.cpp

@@ -227,7 +227,8 @@ static ResultCode ConnectToPort(Handle* out_handle, const char* port_name) {
     auto client_port = it->second;
     auto client_port = it->second;
 
 
     // Connect to the port and retrieve the client endpoint of the connection Session.
     // Connect to the port and retrieve the client endpoint of the connection Session.
-    auto client_session = client_port->Connect();
+    SharedPtr<Kernel::ClientSession> client_session;
+    CASCADE_RESULT(client_session, client_port->Connect());
 
 
     // Note: Threads do not wait for the server endpoint to call
     // Note: Threads do not wait for the server endpoint to call
     // AcceptSession before returning from this call.
     // AcceptSession before returning from this call.