libstrat: convert to experimental new (super-accurate) sf allocation semantics
This commit is contained in:
@@ -15,9 +15,10 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "../sf_common.hpp"
|
||||
#include "sf_cmif_domain_api.hpp"
|
||||
#include "sf_cmif_domain_service_object.hpp"
|
||||
#include <stratosphere/sf/sf_common.hpp>
|
||||
#include <stratosphere/sf/cmif/sf_cmif_domain_api.hpp>
|
||||
#include <stratosphere/sf/cmif/sf_cmif_domain_service_object.hpp>
|
||||
#include <stratosphere/sf/impl/sf_service_object_impl.hpp>
|
||||
|
||||
namespace ams::sf::cmif {
|
||||
|
||||
@@ -39,7 +40,7 @@ namespace ams::sf::cmif {
|
||||
explicit Entry() : owner(nullptr) { /* ... */ }
|
||||
};
|
||||
|
||||
class Domain final : public DomainServiceObject {
|
||||
class Domain final : public DomainServiceObject, private sf::impl::ServiceObjectImplBase2 {
|
||||
NON_COPYABLE(Domain);
|
||||
NON_MOVEABLE(Domain);
|
||||
private:
|
||||
@@ -51,7 +52,17 @@ namespace ams::sf::cmif {
|
||||
explicit Domain(ServerDomainManager *m) : manager(m) { /* ... */ }
|
||||
~Domain();
|
||||
|
||||
void DestroySelf();
|
||||
void DisposeImpl();
|
||||
|
||||
virtual void AddReference() {
|
||||
ServiceObjectImplBase2::AddReferenceImpl();
|
||||
}
|
||||
|
||||
virtual void Release() {
|
||||
if (ServiceObjectImplBase2::ReleaseImpl()) {
|
||||
this->DisposeImpl();
|
||||
}
|
||||
}
|
||||
|
||||
virtual ServerDomainBase *GetServerDomain() override final {
|
||||
return static_cast<ServerDomainBase *>(this);
|
||||
@@ -120,7 +131,7 @@ namespace ams::sf::cmif {
|
||||
}
|
||||
public:
|
||||
static void DestroyDomainServiceObject(DomainServiceObject *obj) {
|
||||
static_cast<Domain *>(obj)->DestroySelf();
|
||||
static_cast<Domain *>(obj)->DisposeImpl();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -84,18 +84,14 @@ namespace ams::sf::cmif {
|
||||
}
|
||||
};
|
||||
|
||||
template<size_t N, class = std::make_index_sequence<N>>
|
||||
class ServiceDispatchTableImpl;
|
||||
|
||||
template<size_t N, size_t... Is>
|
||||
class ServiceDispatchTableImpl<N, std::index_sequence<Is...>> : public ServiceDispatchTableBase {
|
||||
private:
|
||||
template<size_t>
|
||||
using EntryType = ServiceCommandMeta;
|
||||
template<size_t N>
|
||||
class ServiceDispatchTableImpl : public ServiceDispatchTableBase {
|
||||
public:
|
||||
static constexpr size_t NumEntries = N;
|
||||
private:
|
||||
const std::array<ServiceCommandMeta, N> entries;
|
||||
public:
|
||||
explicit constexpr ServiceDispatchTableImpl(EntryType<Is>... args) : entries { args... } { /* ... */ }
|
||||
explicit constexpr ServiceDispatchTableImpl(const std::array<ServiceCommandMeta, N> &e) : entries{e} { /* ... */ }
|
||||
|
||||
Result ProcessMessage(ServiceDispatchContext &ctx, const cmif::PointerAndSize &in_raw_data) const {
|
||||
return this->ProcessMessageImpl(ctx, in_raw_data, this->entries.data(), this->entries.size());
|
||||
@@ -104,20 +100,20 @@ namespace ams::sf::cmif {
|
||||
Result ProcessMessageForMitm(ServiceDispatchContext &ctx, const cmif::PointerAndSize &in_raw_data) const {
|
||||
return this->ProcessMessageForMitmImpl(ctx, in_raw_data, this->entries.data(), this->entries.size());
|
||||
}
|
||||
|
||||
constexpr const std::array<ServiceCommandMeta, N> &GetEntries() const {
|
||||
return this->entries;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template<typename ...Entries>
|
||||
class ServiceDispatchTable : public impl::ServiceDispatchTableImpl<sizeof...(Entries)> {
|
||||
template<size_t N>
|
||||
class ServiceDispatchTable : public impl::ServiceDispatchTableImpl<N> {
|
||||
public:
|
||||
explicit constexpr ServiceDispatchTable(Entries... entries) : impl::ServiceDispatchTableImpl<sizeof...(Entries)>(entries...) { /* ... */ }
|
||||
explicit constexpr ServiceDispatchTable(const std::array<ServiceCommandMeta, N> &e) : impl::ServiceDispatchTableImpl<N>(e) { /* ... */ }
|
||||
};
|
||||
|
||||
#define AMS_SF_CMIF_IMPL_DEFINE_SERVICE_DISPATCH_TABLE \
|
||||
template<typename ServiceImpl> \
|
||||
static constexpr inline ::ams::sf::cmif::ServiceDispatchTable s_CmifServiceDispatchTable
|
||||
|
||||
struct ServiceDispatchMeta {
|
||||
const impl::ServiceDispatchTableBase *DispatchTable;
|
||||
Result (impl::ServiceDispatchTableBase::*ProcessHandler)(ServiceDispatchContext &, const cmif::PointerAndSize &) const;
|
||||
@@ -140,6 +136,16 @@ namespace ams::sf::cmif {
|
||||
static constexpr inline ServiceDispatchMeta Meta{&DispatchTable, ProcessHandlerImpl};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ServiceDispatchTraits<sf::IServiceObject> {
|
||||
static constexpr inline auto DispatchTable = ServiceDispatchTable<0>(std::array<ServiceCommandMeta, 0>{});
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ServiceDispatchTraits<sf::IMitmServiceObject> {
|
||||
static constexpr inline auto DispatchTable = ServiceDispatchTable<0>(std::array<ServiceCommandMeta, 0>{});
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
constexpr ALWAYS_INLINE const ServiceDispatchMeta *GetServiceDispatchMeta() {
|
||||
return &ServiceDispatchTraits<T>::Meta;
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace ams::sf::cmif {
|
||||
|
||||
class ServiceObjectHolder {
|
||||
private:
|
||||
std::shared_ptr<sf::IServiceObject> srv;
|
||||
SharedPointer<IServiceObject> srv;
|
||||
const ServiceDispatchMeta *dispatch_meta;
|
||||
private:
|
||||
/* Copy constructor. */
|
||||
@@ -30,7 +30,7 @@ namespace ams::sf::cmif {
|
||||
ServiceObjectHolder &operator=(const ServiceObjectHolder &o) = delete;
|
||||
public:
|
||||
/* Default constructor, null all members. */
|
||||
ServiceObjectHolder() : srv(nullptr), dispatch_meta(nullptr) { /* ... */ }
|
||||
ServiceObjectHolder() : srv(nullptr, false), dispatch_meta(nullptr) { /* ... */ }
|
||||
|
||||
~ServiceObjectHolder() {
|
||||
this->dispatch_meta = nullptr;
|
||||
@@ -38,9 +38,8 @@ namespace ams::sf::cmif {
|
||||
|
||||
/* Ensure correct type id at runtime through template constructor. */
|
||||
template<typename ServiceImpl>
|
||||
constexpr explicit ServiceObjectHolder(std::shared_ptr<ServiceImpl> &&s) {
|
||||
this->srv = std::move(s);
|
||||
this->dispatch_meta = GetServiceDispatchMeta<ServiceImpl>();
|
||||
constexpr explicit ServiceObjectHolder(SharedPointer<ServiceImpl> &&s) : srv(std::move(s)), dispatch_meta(GetServiceDispatchMeta<ServiceImpl>()) {
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* Move constructor, assignment operator. */
|
||||
@@ -50,13 +49,13 @@ namespace ams::sf::cmif {
|
||||
|
||||
ServiceObjectHolder &operator=(ServiceObjectHolder &&o) {
|
||||
ServiceObjectHolder tmp(std::move(o));
|
||||
tmp.Swap(*this);
|
||||
tmp.swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* State management. */
|
||||
void Swap(ServiceObjectHolder &o) {
|
||||
std::swap(this->srv, o.srv);
|
||||
void swap(ServiceObjectHolder &o) {
|
||||
this->srv.swap(o.srv);
|
||||
std::swap(this->dispatch_meta, o.dispatch_meta);
|
||||
}
|
||||
|
||||
@@ -86,21 +85,21 @@ namespace ams::sf::cmif {
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename ServiceImpl>
|
||||
template<typename Interface>
|
||||
constexpr inline bool IsServiceObjectValid() const {
|
||||
return this->GetServiceId() == GetServiceDispatchMeta<ServiceImpl>()->GetServiceId();
|
||||
return this->GetServiceId() == GetServiceDispatchMeta<Interface>()->GetServiceId();
|
||||
}
|
||||
|
||||
template<typename ServiceImpl>
|
||||
inline std::shared_ptr<ServiceImpl> GetServiceObject() const {
|
||||
if (this->GetServiceId() == GetServiceDispatchMeta<ServiceImpl>()->GetServiceId()) {
|
||||
return std::static_pointer_cast<ServiceImpl>(this->srv);
|
||||
template<typename Interface>
|
||||
inline Interface *GetServiceObject() const {
|
||||
if (this->GetServiceId() == GetServiceDispatchMeta<Interface>()->GetServiceId()) {
|
||||
return static_cast<Interface *>(this->srv.Get());
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
inline sf::IServiceObject *GetServiceObjectUnsafe() const {
|
||||
return this->srv.get();
|
||||
return static_cast<sf::IServiceObject *>(this->srv.Get());
|
||||
}
|
||||
|
||||
/* Processing. */
|
||||
|
||||
Reference in New Issue
Block a user