kernel/hle_ipc: Convert std::shared_ptr IPC header instances to std::optional
There's no real need to use a shared lifetime here, since we don't actually expose them to anything else. This is also kind of an unnecessary use of the heap given the objects themselves are so small; small enough, in fact that changing over to optionals actually reduces the overall size of the HLERequestContext struct (818 bytes to 808 bytes).
This commit is contained in:
parent
69749a88cd
commit
fbb82e61e3
|
@ -350,7 +350,7 @@ public:
|
||||||
template <class T>
|
template <class T>
|
||||||
std::shared_ptr<T> PopIpcInterface() {
|
std::shared_ptr<T> PopIpcInterface() {
|
||||||
ASSERT(context->Session()->IsDomain());
|
ASSERT(context->Session()->IsDomain());
|
||||||
ASSERT(context->GetDomainMessageHeader()->input_object_count > 0);
|
ASSERT(context->GetDomainMessageHeader().input_object_count > 0);
|
||||||
return context->GetDomainRequestHandler<T>(Pop<u32>() - 1);
|
return context->GetDomainRequestHandler<T>(Pop<u32>() - 1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -86,7 +86,7 @@ HLERequestContext::~HLERequestContext() = default;
|
||||||
void HLERequestContext::ParseCommandBuffer(const HandleTable& handle_table, u32_le* src_cmdbuf,
|
void HLERequestContext::ParseCommandBuffer(const HandleTable& handle_table, u32_le* src_cmdbuf,
|
||||||
bool incoming) {
|
bool incoming) {
|
||||||
IPC::RequestParser rp(src_cmdbuf);
|
IPC::RequestParser rp(src_cmdbuf);
|
||||||
command_header = std::make_shared<IPC::CommandHeader>(rp.PopRaw<IPC::CommandHeader>());
|
command_header = rp.PopRaw<IPC::CommandHeader>();
|
||||||
|
|
||||||
if (command_header->type == IPC::CommandType::Close) {
|
if (command_header->type == IPC::CommandType::Close) {
|
||||||
// Close does not populate the rest of the IPC header
|
// Close does not populate the rest of the IPC header
|
||||||
|
@ -95,8 +95,7 @@ void HLERequestContext::ParseCommandBuffer(const HandleTable& handle_table, u32_
|
||||||
|
|
||||||
// If handle descriptor is present, add size of it
|
// If handle descriptor is present, add size of it
|
||||||
if (command_header->enable_handle_descriptor) {
|
if (command_header->enable_handle_descriptor) {
|
||||||
handle_descriptor_header =
|
handle_descriptor_header = rp.PopRaw<IPC::HandleDescriptorHeader>();
|
||||||
std::make_shared<IPC::HandleDescriptorHeader>(rp.PopRaw<IPC::HandleDescriptorHeader>());
|
|
||||||
if (handle_descriptor_header->send_current_pid) {
|
if (handle_descriptor_header->send_current_pid) {
|
||||||
rp.Skip(2, false);
|
rp.Skip(2, false);
|
||||||
}
|
}
|
||||||
|
@ -140,16 +139,15 @@ void HLERequestContext::ParseCommandBuffer(const HandleTable& handle_table, u32_
|
||||||
// If this is an incoming message, only CommandType "Request" has a domain header
|
// If this is an incoming message, only CommandType "Request" has a domain header
|
||||||
// All outgoing domain messages have the domain header, if only incoming has it
|
// All outgoing domain messages have the domain header, if only incoming has it
|
||||||
if (incoming || domain_message_header) {
|
if (incoming || domain_message_header) {
|
||||||
domain_message_header =
|
domain_message_header = rp.PopRaw<IPC::DomainMessageHeader>();
|
||||||
std::make_shared<IPC::DomainMessageHeader>(rp.PopRaw<IPC::DomainMessageHeader>());
|
|
||||||
} else {
|
} else {
|
||||||
if (Session()->IsDomain())
|
if (Session()->IsDomain()) {
|
||||||
LOG_WARNING(IPC, "Domain request has no DomainMessageHeader!");
|
LOG_WARNING(IPC, "Domain request has no DomainMessageHeader!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data_payload_header =
|
data_payload_header = rp.PopRaw<IPC::DataPayloadHeader>();
|
||||||
std::make_shared<IPC::DataPayloadHeader>(rp.PopRaw<IPC::DataPayloadHeader>());
|
|
||||||
|
|
||||||
data_payload_offset = rp.GetCurrentOffset();
|
data_payload_offset = rp.GetCurrentOffset();
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -168,12 +169,12 @@ public:
|
||||||
return buffer_c_desciptors;
|
return buffer_c_desciptors;
|
||||||
}
|
}
|
||||||
|
|
||||||
const IPC::DomainMessageHeader* GetDomainMessageHeader() const {
|
const IPC::DomainMessageHeader& GetDomainMessageHeader() const {
|
||||||
return domain_message_header.get();
|
return domain_message_header.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HasDomainMessageHeader() const {
|
bool HasDomainMessageHeader() const {
|
||||||
return domain_message_header != nullptr;
|
return domain_message_header.has_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper function to read a buffer using the appropriate buffer descriptor
|
/// Helper function to read a buffer using the appropriate buffer descriptor
|
||||||
|
@ -272,10 +273,10 @@ private:
|
||||||
boost::container::small_vector<SharedPtr<Object>, 8> copy_objects;
|
boost::container::small_vector<SharedPtr<Object>, 8> copy_objects;
|
||||||
boost::container::small_vector<std::shared_ptr<SessionRequestHandler>, 8> domain_objects;
|
boost::container::small_vector<std::shared_ptr<SessionRequestHandler>, 8> domain_objects;
|
||||||
|
|
||||||
std::shared_ptr<IPC::CommandHeader> command_header;
|
std::optional<IPC::CommandHeader> command_header;
|
||||||
std::shared_ptr<IPC::HandleDescriptorHeader> handle_descriptor_header;
|
std::optional<IPC::HandleDescriptorHeader> handle_descriptor_header;
|
||||||
std::shared_ptr<IPC::DataPayloadHeader> data_payload_header;
|
std::optional<IPC::DataPayloadHeader> data_payload_header;
|
||||||
std::shared_ptr<IPC::DomainMessageHeader> domain_message_header;
|
std::optional<IPC::DomainMessageHeader> domain_message_header;
|
||||||
std::vector<IPC::BufferDescriptorX> buffer_x_desciptors;
|
std::vector<IPC::BufferDescriptorX> buffer_x_desciptors;
|
||||||
std::vector<IPC::BufferDescriptorABW> buffer_a_desciptors;
|
std::vector<IPC::BufferDescriptorABW> buffer_a_desciptors;
|
||||||
std::vector<IPC::BufferDescriptorABW> buffer_b_desciptors;
|
std::vector<IPC::BufferDescriptorABW> buffer_b_desciptors;
|
||||||
|
|
|
@ -92,41 +92,42 @@ std::size_t ServerSession::NumDomainRequestHandlers() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultCode ServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& context) {
|
ResultCode ServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& context) {
|
||||||
auto* const domain_message_header = context.GetDomainMessageHeader();
|
if (!context.HasDomainMessageHeader()) {
|
||||||
if (domain_message_header) {
|
return RESULT_SUCCESS;
|
||||||
// Set domain handlers in HLE context, used for domain objects (IPC interfaces) as inputs
|
|
||||||
context.SetDomainRequestHandlers(domain_request_handlers);
|
|
||||||
|
|
||||||
// If there is a DomainMessageHeader, then this is CommandType "Request"
|
|
||||||
const u32 object_id{context.GetDomainMessageHeader()->object_id};
|
|
||||||
switch (domain_message_header->command) {
|
|
||||||
case IPC::DomainMessageHeader::CommandType::SendMessage:
|
|
||||||
if (object_id > domain_request_handlers.size()) {
|
|
||||||
LOG_CRITICAL(IPC,
|
|
||||||
"object_id {} is too big! This probably means a recent service call "
|
|
||||||
"to {} needed to return a new interface!",
|
|
||||||
object_id, name);
|
|
||||||
UNREACHABLE();
|
|
||||||
return RESULT_SUCCESS; // Ignore error if asserts are off
|
|
||||||
}
|
|
||||||
return domain_request_handlers[object_id - 1]->HandleSyncRequest(context);
|
|
||||||
|
|
||||||
case IPC::DomainMessageHeader::CommandType::CloseVirtualHandle: {
|
|
||||||
LOG_DEBUG(IPC, "CloseVirtualHandle, object_id=0x{:08X}", object_id);
|
|
||||||
|
|
||||||
domain_request_handlers[object_id - 1] = nullptr;
|
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{context, 2};
|
|
||||||
rb.Push(RESULT_SUCCESS);
|
|
||||||
return RESULT_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_CRITICAL(IPC, "Unknown domain command={}",
|
|
||||||
static_cast<int>(domain_message_header->command.Value()));
|
|
||||||
ASSERT(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set domain handlers in HLE context, used for domain objects (IPC interfaces) as inputs
|
||||||
|
context.SetDomainRequestHandlers(domain_request_handlers);
|
||||||
|
|
||||||
|
// If there is a DomainMessageHeader, then this is CommandType "Request"
|
||||||
|
const auto& domain_message_header = context.GetDomainMessageHeader();
|
||||||
|
const u32 object_id{domain_message_header.object_id};
|
||||||
|
switch (domain_message_header.command) {
|
||||||
|
case IPC::DomainMessageHeader::CommandType::SendMessage:
|
||||||
|
if (object_id > domain_request_handlers.size()) {
|
||||||
|
LOG_CRITICAL(IPC,
|
||||||
|
"object_id {} is too big! This probably means a recent service call "
|
||||||
|
"to {} needed to return a new interface!",
|
||||||
|
object_id, name);
|
||||||
|
UNREACHABLE();
|
||||||
|
return RESULT_SUCCESS; // Ignore error if asserts are off
|
||||||
|
}
|
||||||
|
return domain_request_handlers[object_id - 1]->HandleSyncRequest(context);
|
||||||
|
|
||||||
|
case IPC::DomainMessageHeader::CommandType::CloseVirtualHandle: {
|
||||||
|
LOG_DEBUG(IPC, "CloseVirtualHandle, object_id=0x{:08X}", object_id);
|
||||||
|
|
||||||
|
domain_request_handlers[object_id - 1] = nullptr;
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{context, 2};
|
||||||
|
rb.Push(RESULT_SUCCESS);
|
||||||
|
return RESULT_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_CRITICAL(IPC, "Unknown domain command={}",
|
||||||
|
static_cast<int>(domain_message_header.command.Value()));
|
||||||
|
ASSERT(false);
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Reference in New Issue