Merge pull request #2210 from lioncash/optional
kernel/hle_ipc: Convert std::shared_ptr IPC header instances to std::optional
This commit is contained in:
commit
9909d40530
|
@ -24,7 +24,7 @@ matrix:
|
||||||
- os: osx
|
- os: osx
|
||||||
env: NAME="macos build"
|
env: NAME="macos build"
|
||||||
sudo: false
|
sudo: false
|
||||||
osx_image: xcode10
|
osx_image: xcode10.1
|
||||||
install: "./.travis/macos/deps.sh"
|
install: "./.travis/macos/deps.sh"
|
||||||
script: "./.travis/macos/build.sh"
|
script: "./.travis/macos/build.sh"
|
||||||
after_success: "./.travis/macos/upload.sh"
|
after_success: "./.travis/macos/upload.sh"
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
export MACOSX_DEPLOYMENT_TARGET=10.13
|
export MACOSX_DEPLOYMENT_TARGET=10.14
|
||||||
export Qt5_DIR=$(brew --prefix)/opt/qt5
|
export Qt5_DIR=$(brew --prefix)/opt/qt5
|
||||||
export UNICORNDIR=$(pwd)/externals/unicorn
|
export UNICORNDIR=$(pwd)/externals/unicorn
|
||||||
export PATH="/usr/local/opt/ccache/libexec:$PATH"
|
export PATH="/usr/local/opt/ccache/libexec:$PATH"
|
||||||
|
|
|
@ -111,12 +111,6 @@
|
||||||
template <std::size_t Position, std::size_t Bits, typename T>
|
template <std::size_t Position, std::size_t Bits, typename T>
|
||||||
struct BitField {
|
struct BitField {
|
||||||
private:
|
private:
|
||||||
// We hide the copy assigment operator here, because the default copy
|
|
||||||
// assignment would copy the full storage value, rather than just the bits
|
|
||||||
// relevant to this particular bit field.
|
|
||||||
// We don't delete it because we want BitField to be trivially copyable.
|
|
||||||
constexpr BitField& operator=(const BitField&) = default;
|
|
||||||
|
|
||||||
// UnderlyingType is T for non-enum types and the underlying type of T if
|
// UnderlyingType is T for non-enum types and the underlying type of T if
|
||||||
// T is an enumeration. Note that T is wrapped within an enable_if in the
|
// T is an enumeration. Note that T is wrapped within an enable_if in the
|
||||||
// former case to workaround compile errors which arise when using
|
// former case to workaround compile errors which arise when using
|
||||||
|
@ -163,9 +157,13 @@ public:
|
||||||
BitField(T val) = delete;
|
BitField(T val) = delete;
|
||||||
BitField& operator=(T val) = delete;
|
BitField& operator=(T val) = delete;
|
||||||
|
|
||||||
// Force default constructor to be created
|
constexpr BitField() noexcept = default;
|
||||||
// so that we can use this within unions
|
|
||||||
constexpr BitField() = default;
|
constexpr BitField(const BitField&) noexcept = default;
|
||||||
|
constexpr BitField& operator=(const BitField&) noexcept = default;
|
||||||
|
|
||||||
|
constexpr BitField(BitField&&) noexcept = default;
|
||||||
|
constexpr BitField& operator=(BitField&&) noexcept = default;
|
||||||
|
|
||||||
constexpr FORCE_INLINE operator T() const {
|
constexpr FORCE_INLINE operator T() const {
|
||||||
return Value();
|
return Value();
|
||||||
|
|
|
@ -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