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:
bunnei 2019-03-08 16:35:57 -05:00 committed by GitHub
commit 9909d40530
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 58 additions and 60 deletions

View file

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

View file

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

View file

@ -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();

View file

@ -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);
} }
}; };

View file

@ -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();

View file

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

View file

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