mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-11-15 03:27:49 +01:00
kern: SvcConnectToNamedPort
This commit is contained in:
parent
a2eb93fde8
commit
7400a8ff68
@ -177,10 +177,12 @@ namespace ams::kern {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T> requires std::derived_from<T, KAutoObject>
|
||||||
class KScopedAutoObject {
|
class KScopedAutoObject {
|
||||||
static_assert(std::is_base_of<KAutoObject, T>::value);
|
|
||||||
NON_COPYABLE(KScopedAutoObject);
|
NON_COPYABLE(KScopedAutoObject);
|
||||||
|
private:
|
||||||
|
template<typename U>
|
||||||
|
friend class KScopedAutoObject;
|
||||||
private:
|
private:
|
||||||
T *obj;
|
T *obj;
|
||||||
private:
|
private:
|
||||||
@ -202,12 +204,32 @@ namespace ams::kern {
|
|||||||
this->obj = nullptr;
|
this->obj = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr ALWAYS_INLINE KScopedAutoObject(KScopedAutoObject &&rhs) {
|
template<typename U>
|
||||||
this->obj = rhs.obj;
|
constexpr ALWAYS_INLINE KScopedAutoObject(KScopedAutoObject<U> &&rhs) {
|
||||||
rhs.obj = nullptr;
|
if constexpr (std::same_as<T, U>) {
|
||||||
|
this->obj = rhs.obj;
|
||||||
|
rhs.obj = nullptr;
|
||||||
|
} else {
|
||||||
|
T *derived = rhs.obj->template DynamicCast<T *>();
|
||||||
|
if (derived == nullptr) {
|
||||||
|
rhs.obj->Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
this->obj = derived;
|
||||||
|
rhs.obj = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr ALWAYS_INLINE KScopedAutoObject &operator=(KScopedAutoObject &&rhs) {
|
template<typename U>
|
||||||
|
constexpr ALWAYS_INLINE KScopedAutoObject &operator=(KScopedAutoObject<U> &&rhs) {
|
||||||
|
if constexpr (!std::same_as<T, U>) {
|
||||||
|
T *derived = rhs.obj->template DynamicCast<T *>();
|
||||||
|
if (derived == nullptr) {
|
||||||
|
rhs.obj->Close();
|
||||||
|
}
|
||||||
|
rhs.obj = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
rhs.Swap(*this);
|
rhs.Swap(*this);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,10 @@
|
|||||||
namespace ams::kern {
|
namespace ams::kern {
|
||||||
|
|
||||||
class KPort;
|
class KPort;
|
||||||
|
class KSession;
|
||||||
|
class KClientSession;
|
||||||
|
class KLightSession;
|
||||||
|
class KLightClientSession;
|
||||||
|
|
||||||
class KClientPort final : public KSynchronizationObject {
|
class KClientPort final : public KSynchronizationObject {
|
||||||
MESOSPHERE_AUTOOBJECT_TRAITS(KClientPort, KSynchronizationObject);
|
MESOSPHERE_AUTOOBJECT_TRAITS(KClientPort, KSynchronizationObject);
|
||||||
@ -33,6 +37,8 @@ namespace ams::kern {
|
|||||||
virtual ~KClientPort() { /* ... */ }
|
virtual ~KClientPort() { /* ... */ }
|
||||||
|
|
||||||
void Initialize(KPort *parent, s32 max_sessions);
|
void Initialize(KPort *parent, s32 max_sessions);
|
||||||
|
void OnSessionFinalized();
|
||||||
|
void OnServerClosed();
|
||||||
|
|
||||||
constexpr const KPort *GetParent() const { return this->parent; }
|
constexpr const KPort *GetParent() const { return this->parent; }
|
||||||
|
|
||||||
@ -43,6 +49,7 @@ namespace ams::kern {
|
|||||||
virtual bool IsSignaled() const override;
|
virtual bool IsSignaled() const override;
|
||||||
|
|
||||||
/* TODO: More of KClientPort. */
|
/* TODO: More of KClientPort. */
|
||||||
|
Result CreateSession(KClientSession **out);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,7 @@ namespace ams::kern {
|
|||||||
constexpr const KSession *GetParent() const { return this->parent; }
|
constexpr const KSession *GetParent() const { return this->parent; }
|
||||||
|
|
||||||
/* TODO: More of KClientSession. */
|
/* TODO: More of KClientSession. */
|
||||||
|
void OnServerClosed();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,11 @@ namespace ams::kern {
|
|||||||
|
|
||||||
return Delete(obj.GetPointerUnsafe(), name);
|
return Delete(obj.GetPointerUnsafe(), name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Derived> requires std::derived_from<Derived, KAutoObject>
|
||||||
|
static KScopedAutoObject<Derived> Find(const char *name) {
|
||||||
|
return Find(name);
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
static KScopedAutoObject<KAutoObject> FindImpl(const char *name);
|
static KScopedAutoObject<KAutoObject> FindImpl(const char *name);
|
||||||
|
|
||||||
|
@ -22,6 +22,9 @@
|
|||||||
|
|
||||||
namespace ams::kern {
|
namespace ams::kern {
|
||||||
|
|
||||||
|
class KServerSession;
|
||||||
|
class KLightServerSession;
|
||||||
|
|
||||||
class KPort final : public KAutoObjectWithSlabHeapAndContainer<KPort, KAutoObjectWithList> {
|
class KPort final : public KAutoObjectWithSlabHeapAndContainer<KPort, KAutoObjectWithList> {
|
||||||
MESOSPHERE_AUTOOBJECT_TRAITS(KPort, KAutoObject);
|
MESOSPHERE_AUTOOBJECT_TRAITS(KPort, KAutoObject);
|
||||||
private:
|
private:
|
||||||
@ -50,7 +53,8 @@ namespace ams::kern {
|
|||||||
uintptr_t GetName() const { return this->name; }
|
uintptr_t GetName() const { return this->name; }
|
||||||
bool IsLight() const { return this->is_light; }
|
bool IsLight() const { return this->is_light; }
|
||||||
|
|
||||||
/* TODO: More of KPort */
|
Result EnqueueSession(KServerSession *session);
|
||||||
|
Result EnqueueSession(KLightServerSession *session);
|
||||||
|
|
||||||
KClientPort &GetClientPort() { return this->client; }
|
KClientPort &GetClientPort() { return this->client; }
|
||||||
KServerPort &GetServerPort() { return this->server; }
|
KServerPort &GetServerPort() { return this->server; }
|
||||||
|
@ -38,6 +38,8 @@ namespace ams::kern {
|
|||||||
virtual ~KServerPort() { /* ... */ }
|
virtual ~KServerPort() { /* ... */ }
|
||||||
|
|
||||||
void Initialize(KPort *parent);
|
void Initialize(KPort *parent);
|
||||||
|
void EnqueueSession(KServerSession *session);
|
||||||
|
void EnqueueSession(KLightServerSession *session);
|
||||||
|
|
||||||
constexpr const KPort *GetParent() const { return this->parent; }
|
constexpr const KPort *GetParent() const { return this->parent; }
|
||||||
|
|
||||||
@ -47,7 +49,7 @@ namespace ams::kern {
|
|||||||
virtual void Destroy() override;
|
virtual void Destroy() override;
|
||||||
virtual bool IsSignaled() const override;
|
virtual bool IsSignaled() const override;
|
||||||
|
|
||||||
/* TODO: More of KClientPort. */
|
/* TODO: More of KServerPort. */
|
||||||
private:
|
private:
|
||||||
void CleanupSessions();
|
void CleanupSessions();
|
||||||
/* TODO: This is a placeholder definition. */
|
/* TODO: This is a placeholder definition. */
|
||||||
|
@ -36,13 +36,16 @@ namespace ams::kern {
|
|||||||
constexpr KServerSession() : parent(), request_list(), current_request(), lock() { /* ... */ }
|
constexpr KServerSession() : parent(), request_list(), current_request(), lock() { /* ... */ }
|
||||||
virtual ~KServerSession() { /* ... */ }
|
virtual ~KServerSession() { /* ... */ }
|
||||||
|
|
||||||
void Initialize(KSession *parent);
|
void Initialize(KSession *p) { this->parent = p; }
|
||||||
|
|
||||||
constexpr const KSession *GetParent() const { return this->parent; }
|
constexpr const KSession *GetParent() const { return this->parent; }
|
||||||
|
|
||||||
virtual bool IsSignaled() const override { MESOSPHERE_UNIMPLEMENTED(); }
|
virtual bool IsSignaled() const override { MESOSPHERE_UNIMPLEMENTED(); }
|
||||||
|
|
||||||
/* TODO: More of KServerSession. */
|
/* TODO: More of KServerSession. */
|
||||||
|
Result OnRequest(KSessionRequest *request);
|
||||||
|
|
||||||
|
void OnClientClosed();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -51,12 +51,21 @@ namespace ams::kern {
|
|||||||
|
|
||||||
virtual ~KSession() { /* ... */ }
|
virtual ~KSession() { /* ... */ }
|
||||||
|
|
||||||
|
void Initialize(KClientPort *client_port, uintptr_t name);
|
||||||
|
virtual void Finalize() override;
|
||||||
|
|
||||||
virtual bool IsInitialized() const override { return this->initialized; }
|
virtual bool IsInitialized() const override { return this->initialized; }
|
||||||
virtual uintptr_t GetPostDestroyArgument() const override { return reinterpret_cast<uintptr_t>(this->process); }
|
virtual uintptr_t GetPostDestroyArgument() const override { return reinterpret_cast<uintptr_t>(this->process); }
|
||||||
|
|
||||||
static void PostDestroy(uintptr_t arg);
|
static void PostDestroy(uintptr_t arg);
|
||||||
|
|
||||||
/* TODO: This is a placeholder definition. */
|
void OnServerClosed();
|
||||||
|
void OnClientClosed();
|
||||||
|
|
||||||
|
bool IsServerClosed() const { return this->state != State::Normal; }
|
||||||
|
bool IsClientClosed() const { return this->state != State::Normal; }
|
||||||
|
|
||||||
|
Result OnRequest(KSessionRequest *request) { return this->server.OnRequest(request); }
|
||||||
|
|
||||||
KClientSession &GetClientSession() { return this->client; }
|
KClientSession &GetClientSession() { return this->client; }
|
||||||
KServerSession &GetServerSession() { return this->server; }
|
KServerSession &GetServerSession() { return this->server; }
|
||||||
|
@ -25,6 +25,19 @@ namespace ams::kern {
|
|||||||
this->max_sessions = max_sessions;
|
this->max_sessions = max_sessions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KClientPort::OnSessionFinalized() {
|
||||||
|
KScopedSchedulerLock sl;
|
||||||
|
|
||||||
|
const auto prev = this->num_sessions--;
|
||||||
|
if (prev == this->max_sessions) {
|
||||||
|
this->NotifyAvailable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void KClientPort::OnServerClosed() {
|
||||||
|
MESOSPHERE_ASSERT_THIS();
|
||||||
|
}
|
||||||
|
|
||||||
bool KClientPort::IsLight() const {
|
bool KClientPort::IsLight() const {
|
||||||
return this->GetParent()->IsLight();
|
return this->GetParent()->IsLight();
|
||||||
}
|
}
|
||||||
@ -43,4 +56,71 @@ namespace ams::kern {
|
|||||||
return this->num_sessions < this->max_sessions;
|
return this->num_sessions < this->max_sessions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result KClientPort::CreateSession(KClientSession **out) {
|
||||||
|
MESOSPHERE_ASSERT_THIS();
|
||||||
|
|
||||||
|
/* Reserve a new session from the resource limit. */
|
||||||
|
KScopedResourceReservation session_reservation(GetCurrentProcessPointer(), ams::svc::LimitableResource_SessionCountMax);
|
||||||
|
R_UNLESS(session_reservation.Succeeded(), svc::ResultLimitReached());
|
||||||
|
|
||||||
|
/* Update the session counts. */
|
||||||
|
{
|
||||||
|
/* Atomically increment the number of sessions. */
|
||||||
|
s32 new_sessions;
|
||||||
|
{
|
||||||
|
const auto max = this->max_sessions;
|
||||||
|
auto cur_sessions = this->num_sessions.load(std::memory_order_acquire);
|
||||||
|
do {
|
||||||
|
R_UNLESS(cur_sessions < max, svc::ResultOutOfSessions());
|
||||||
|
new_sessions = cur_sessions + 1;
|
||||||
|
} while (!this->num_sessions.compare_exchange_weak(cur_sessions, new_sessions, std::memory_order_relaxed));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Atomically update the peak session tracking. */
|
||||||
|
{
|
||||||
|
auto peak = this->peak_sessions.load(std::memory_order_acquire);
|
||||||
|
do {
|
||||||
|
if (peak >= new_sessions) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (!this->peak_sessions.compare_exchange_weak(peak, new_sessions, std::memory_order_relaxed));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create a new session. */
|
||||||
|
KSession *session = KSession::Create();
|
||||||
|
if (session == nullptr) {
|
||||||
|
/* Decrement the session count. */
|
||||||
|
const auto prev = this->num_sessions--;
|
||||||
|
if (prev == this->max_sessions) {
|
||||||
|
this->NotifyAvailable();
|
||||||
|
}
|
||||||
|
|
||||||
|
return svc::ResultOutOfResource();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize the session. */
|
||||||
|
session->Initialize(this, this->parent->GetName());
|
||||||
|
|
||||||
|
/* Commit the session reservation. */
|
||||||
|
session_reservation.Commit();
|
||||||
|
|
||||||
|
/* Register the session. */
|
||||||
|
KSession::Register(session);
|
||||||
|
auto session_guard = SCOPE_GUARD {
|
||||||
|
session->GetClientSession().Close();
|
||||||
|
session->GetServerSession().Close();
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Enqueue the session with our parent. */
|
||||||
|
R_TRY(this->parent->EnqueueSession(std::addressof(session->GetServerSession())));
|
||||||
|
|
||||||
|
/* We succeeded, so set the output. */
|
||||||
|
session_guard.Cancel();
|
||||||
|
*out = std::addressof(session->GetClientSession());
|
||||||
|
return ResultSuccess();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
24
libraries/libmesosphere/source/kern_k_client_session.cpp
Normal file
24
libraries/libmesosphere/source/kern_k_client_session.cpp
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#include <mesosphere.hpp>
|
||||||
|
|
||||||
|
namespace ams::kern {
|
||||||
|
|
||||||
|
void KClientSession::OnServerClosed() {
|
||||||
|
MESOSPHERE_ASSERT_THIS();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -34,11 +34,41 @@ namespace ams::kern {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void KPort::OnClientClosed() {
|
void KPort::OnClientClosed() {
|
||||||
MESOSPHERE_UNIMPLEMENTED();
|
MESOSPHERE_ASSERT_THIS();
|
||||||
|
|
||||||
|
KScopedSchedulerLock sl;
|
||||||
|
|
||||||
|
if (this->state == State::Normal) {
|
||||||
|
this->state = State::ClientClosed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KPort::OnServerClosed() {
|
void KPort::OnServerClosed() {
|
||||||
MESOSPHERE_UNIMPLEMENTED();
|
MESOSPHERE_ASSERT_THIS();
|
||||||
|
|
||||||
|
KScopedSchedulerLock sl;
|
||||||
|
|
||||||
|
if (this->state == State::Normal) {
|
||||||
|
this->state = State::ServerClosed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Result KPort::EnqueueSession(KServerSession *session) {
|
||||||
|
KScopedSchedulerLock sl;
|
||||||
|
|
||||||
|
R_UNLESS(this->state == State::Normal, svc::ResultPortClosed());
|
||||||
|
|
||||||
|
this->server.EnqueueSession(session);
|
||||||
|
return ResultSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result KPort::EnqueueSession(KLightServerSession *session) {
|
||||||
|
KScopedSchedulerLock sl;
|
||||||
|
|
||||||
|
R_UNLESS(this->state == State::Normal, svc::ResultPortClosed());
|
||||||
|
|
||||||
|
this->server.EnqueueSession(session);
|
||||||
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -89,7 +89,33 @@ namespace ams::kern {
|
|||||||
if (this->IsLight()) {
|
if (this->IsLight()) {
|
||||||
return !this->light_session_list.empty();
|
return !this->light_session_list.empty();
|
||||||
} else {
|
} else {
|
||||||
return this->session_list.empty();
|
return !this->session_list.empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void KServerPort::EnqueueSession(KServerSession *session) {
|
||||||
|
MESOSPHERE_ASSERT_THIS();
|
||||||
|
MESOSPHERE_ASSERT(!this->IsLight());
|
||||||
|
|
||||||
|
KScopedSchedulerLock sl;
|
||||||
|
|
||||||
|
/* Add the session to our queue. */
|
||||||
|
this->session_list.push_back(*session);
|
||||||
|
if (this->session_list.size() == 1) {
|
||||||
|
this->NotifyAvailable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void KServerPort::EnqueueSession(KLightServerSession *session) {
|
||||||
|
MESOSPHERE_ASSERT_THIS();
|
||||||
|
MESOSPHERE_ASSERT(this->IsLight());
|
||||||
|
|
||||||
|
KScopedSchedulerLock sl;
|
||||||
|
|
||||||
|
/* Add the session to our queue. */
|
||||||
|
this->light_session_list.push_back(*session);
|
||||||
|
if (this->light_session_list.size() == 1) {
|
||||||
|
this->NotifyAvailable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
29
libraries/libmesosphere/source/kern_k_server_session.cpp
Normal file
29
libraries/libmesosphere/source/kern_k_server_session.cpp
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#include <mesosphere.hpp>
|
||||||
|
|
||||||
|
namespace ams::kern {
|
||||||
|
|
||||||
|
Result KServerSession::OnRequest(KSessionRequest *request) {
|
||||||
|
MESOSPHERE_UNIMPLEMENTED();
|
||||||
|
}
|
||||||
|
|
||||||
|
void KServerSession::OnClientClosed() {
|
||||||
|
MESOSPHERE_ASSERT_THIS();
|
||||||
|
MESOSPHERE_UNIMPLEMENTED();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
84
libraries/libmesosphere/source/kern_k_session.cpp
Normal file
84
libraries/libmesosphere/source/kern_k_session.cpp
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#include <mesosphere.hpp>
|
||||||
|
|
||||||
|
namespace ams::kern {
|
||||||
|
|
||||||
|
void KSession::Initialize(KClientPort *client_port, uintptr_t name) {
|
||||||
|
MESOSPHERE_ASSERT_THIS();
|
||||||
|
|
||||||
|
/* Increment reference count. */
|
||||||
|
this->Open();
|
||||||
|
|
||||||
|
/* Create our sub sessions. */
|
||||||
|
KAutoObject::Create(std::addressof(this->server));
|
||||||
|
KAutoObject::Create(std::addressof(this->client));
|
||||||
|
|
||||||
|
/* Initialize our sub sessions. */
|
||||||
|
this->server.Initialize(this);
|
||||||
|
this->client.Initialize(this);
|
||||||
|
|
||||||
|
/* Set state and name. */
|
||||||
|
this->state = State::Normal;
|
||||||
|
this->name = name;
|
||||||
|
|
||||||
|
/* Set our owner process. */
|
||||||
|
this->process = GetCurrentProcessPointer();
|
||||||
|
this->process->Open();
|
||||||
|
|
||||||
|
/* Set our port. */
|
||||||
|
this->port = port;
|
||||||
|
if (this->port != nullptr) {
|
||||||
|
this->port->Open();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mark initialized. */
|
||||||
|
this->initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KSession::Finalize() {
|
||||||
|
if (this->port != nullptr) {
|
||||||
|
this->port->OnSessionFinalized();
|
||||||
|
this->port->Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void KSession::OnServerClosed() {
|
||||||
|
MESOSPHERE_ASSERT_THIS();
|
||||||
|
|
||||||
|
if (this->state == State::Normal) {
|
||||||
|
this->state = State::ServerClosed;
|
||||||
|
this->client.OnServerClosed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void KSession::OnClientClosed() {
|
||||||
|
MESOSPHERE_ASSERT_THIS();
|
||||||
|
|
||||||
|
if (this->state == State::Normal) {
|
||||||
|
this->state = State::ClientClosed;
|
||||||
|
this->server.OnClientClosed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void KSession::PostDestroy(uintptr_t arg) {
|
||||||
|
/* Release the session count resource the owner process holds. */
|
||||||
|
KProcess *owner = reinterpret_cast<KProcess *>(arg);
|
||||||
|
owner->ReleaseResource(ams::svc::LimitableResource_SessionCountMax, 1);
|
||||||
|
owner->Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -77,12 +77,47 @@ namespace ams::kern::svc {
|
|||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result ConnectToNamedPort(ams::svc::Handle *out, KUserPointer<const char *> user_name) {
|
||||||
|
/* Copy the provided name from user memory to kernel memory. */
|
||||||
|
char name[KObjectName::NameLengthMax] = {};
|
||||||
|
R_TRY(user_name.CopyStringTo(name, sizeof(name)));
|
||||||
|
|
||||||
|
/* Validate that name is valid. */
|
||||||
|
R_UNLESS(name[sizeof(name) - 1] == '\x00', svc::ResultOutOfRange());
|
||||||
|
|
||||||
|
MESOSPHERE_LOG("%s: ConnectToNamedPort(%s) was called\n", GetCurrentProcess().GetName(), name);
|
||||||
|
|
||||||
|
/* Get the current handle table. */
|
||||||
|
auto &handle_table = GetCurrentProcess().GetHandleTable();
|
||||||
|
|
||||||
|
/* Find the client port. */
|
||||||
|
auto port = KObjectName::Find<KClientPort>(name);
|
||||||
|
R_UNLESS(port.IsNotNull(), svc::ResultNotFound());
|
||||||
|
|
||||||
|
/* Reserve a handle for the port. */
|
||||||
|
/* NOTE: Nintendo really does write directly to the output handle here. */
|
||||||
|
R_TRY(handle_table.Reserve(out));
|
||||||
|
auto handle_guard = SCOPE_GUARD { handle_table.Unreserve(*out); };
|
||||||
|
|
||||||
|
/* Create a session. */
|
||||||
|
KClientSession *session;
|
||||||
|
R_TRY(port->CreateSession(std::addressof(session)));
|
||||||
|
|
||||||
|
/* Register the session in the table, close the extra reference. */
|
||||||
|
handle_table.Register(*out, session);
|
||||||
|
session->Close();
|
||||||
|
|
||||||
|
/* We succeeded. */
|
||||||
|
handle_guard.Cancel();
|
||||||
|
return ResultSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================= 64 ABI ============================= */
|
/* ============================= 64 ABI ============================= */
|
||||||
|
|
||||||
Result ConnectToNamedPort64(ams::svc::Handle *out_handle, KUserPointer<const char *> name) {
|
Result ConnectToNamedPort64(ams::svc::Handle *out_handle, KUserPointer<const char *> name) {
|
||||||
MESOSPHERE_PANIC("Stubbed SvcConnectToNamedPort64 was called.");
|
return ConnectToNamedPort(out_handle, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CreatePort64(ams::svc::Handle *out_server_handle, ams::svc::Handle *out_client_handle, int32_t max_sessions, bool is_light, ams::svc::Address name) {
|
Result CreatePort64(ams::svc::Handle *out_server_handle, ams::svc::Handle *out_client_handle, int32_t max_sessions, bool is_light, ams::svc::Address name) {
|
||||||
@ -100,7 +135,7 @@ namespace ams::kern::svc {
|
|||||||
/* ============================= 64From32 ABI ============================= */
|
/* ============================= 64From32 ABI ============================= */
|
||||||
|
|
||||||
Result ConnectToNamedPort64From32(ams::svc::Handle *out_handle, KUserPointer<const char *> name) {
|
Result ConnectToNamedPort64From32(ams::svc::Handle *out_handle, KUserPointer<const char *> name) {
|
||||||
MESOSPHERE_PANIC("Stubbed SvcConnectToNamedPort64From32 was called.");
|
return ConnectToNamedPort(out_handle, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CreatePort64From32(ams::svc::Handle *out_server_handle, ams::svc::Handle *out_client_handle, int32_t max_sessions, bool is_light, ams::svc::Address name) {
|
Result CreatePort64From32(ams::svc::Handle *out_server_handle, ams::svc::Handle *out_client_handle, int32_t max_sessions, bool is_light, ams::svc::Address name) {
|
||||||
|
Loading…
Reference in New Issue
Block a user