Return an error code when connecting to a saturated port.

The error code was taken from the 3DS kernel.
This commit is contained in:
Subv 2016-12-05 13:59:57 -05:00
parent 61a2fe8c3b
commit c93c5a72bb
5 changed files with 20 additions and 7 deletions

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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 res = client_session.Code();
cmd_buff[3] = Kernel::g_handle_table.Create(client_session).MoveFrom();
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());

View File

@ -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.