ams: support building unit test programs on windows/linux/macos
This commit is contained in:
@@ -15,13 +15,14 @@
|
||||
*/
|
||||
#pragma once
|
||||
#include <vapours.hpp>
|
||||
#include <stratosphere/tipc/tipc_message_types.hpp>
|
||||
#include <stratosphere/tipc/tipc_service_object_base.hpp>
|
||||
#include <stratosphere/tipc/impl/tipc_impl_command_serialization.hpp>
|
||||
|
||||
namespace ams::tipc::impl {
|
||||
|
||||
template<typename T>
|
||||
concept HasDefaultServiceCommandProcessor = requires (T &t, const svc::ipc::MessageBuffer &message_buffer) {
|
||||
concept HasDefaultServiceCommandProcessor = requires (T &t, const MessageBuffer &message_buffer) {
|
||||
{ t.ProcessDefaultServiceCommand(message_buffer) } -> std::same_as<Result>;
|
||||
};
|
||||
|
||||
@@ -129,7 +130,7 @@ namespace ams::tipc::impl {
|
||||
constexpr explicit ImplTemplateBaseT(Args &&...args) : ImplHolder(std::forward<Args>(args)...) { /* ... */ } \
|
||||
private: \
|
||||
template<typename ImplType> \
|
||||
ALWAYS_INLINE Result ProcessDefaultMethod(ImplType *impl, const svc::ipc::MessageBuffer &message_buffer) const { \
|
||||
ALWAYS_INLINE Result ProcessDefaultMethod(ImplType *impl, const MessageBuffer &message_buffer) const { \
|
||||
/* Handle a default command. */ \
|
||||
if constexpr (HasDefaultServiceCommandProcessor<ImplType>) { \
|
||||
return impl->ProcessDefaultServiceCommand(message_buffer); \
|
||||
@@ -139,7 +140,7 @@ namespace ams::tipc::impl {
|
||||
} \
|
||||
\
|
||||
template<u16 CommandId, typename ImplType> \
|
||||
ALWAYS_INLINE Result ProcessMethodById(ImplType *impl, const svc::ipc::MessageBuffer &message_buffer, hos::Version fw_ver) const { \
|
||||
ALWAYS_INLINE Result ProcessMethodById(ImplType *impl, const MessageBuffer &message_buffer, hos::Version fw_ver) const { \
|
||||
CMD_MACRO(ImplType, AMS_TIPC_IMPL_PROCESS_METHOD_REQUEST_BY_ID) \
|
||||
\
|
||||
return this->ProcessDefaultMethod<ImplType>(impl, message_buffer); \
|
||||
@@ -159,10 +160,10 @@ namespace ams::tipc::impl {
|
||||
static_assert(::NAMESPACE::Is##INTERFACE<ImplType>); \
|
||||
\
|
||||
/* Get accessor to the message buffer. */ \
|
||||
const svc::ipc::MessageBuffer message_buffer(svc::ipc::GetMessageBuffer()); \
|
||||
const MessageBuffer message_buffer(tipc::GetMessageBuffer()); \
|
||||
\
|
||||
/* Get decision variables. */ \
|
||||
const auto tag = svc::ipc::MessageBuffer::MessageHeader(message_buffer).GetTag(); \
|
||||
const auto tag = MessageBuffer::MessageHeader(message_buffer).GetTag(); \
|
||||
const auto fw_ver = IsFirmwareVersionAlwaysValid() ? hos::Version_Current : hos::GetVersion(); \
|
||||
\
|
||||
/* Process against the command ids. */ \
|
||||
|
||||
@@ -29,6 +29,7 @@ namespace ams::tipc {
|
||||
|
||||
}
|
||||
|
||||
#if defined(ATMOSPHERE_OS_HORIZON)
|
||||
namespace ams::tipc::impl {
|
||||
|
||||
/* Machinery for filtering type lists. */
|
||||
@@ -302,21 +303,21 @@ namespace ams::tipc::impl {
|
||||
/* tipc-specific accessors. */
|
||||
static constexpr bool HasInSpecialHeader = HasProcessId || NumInHandles > 0;
|
||||
|
||||
static constexpr svc::ipc::MessageBuffer::MessageHeader InMessageHeader{CommandId, HasInSpecialHeader, 0, NumInBuffers, NumOutBuffers, 0, InDataSize / sizeof(u32), 0};
|
||||
static constexpr svc::ipc::MessageBuffer::SpecialHeader InSpecialHeader{HasProcessId, NumInCopyHandles, NumInMoveHandles, HasInSpecialHeader};
|
||||
static constexpr MessageBuffer::MessageHeader InMessageHeader{CommandId, HasInSpecialHeader, 0, NumInBuffers, NumOutBuffers, 0, InDataSize / sizeof(u32), 0};
|
||||
static constexpr MessageBuffer::SpecialHeader InSpecialHeader{HasProcessId, NumInCopyHandles, NumInMoveHandles, HasInSpecialHeader};
|
||||
|
||||
static constexpr auto InMessageProcessIdIndex = svc::ipc::MessageBuffer::GetSpecialDataIndex(InMessageHeader, InSpecialHeader);
|
||||
static constexpr auto InMessageHandleIndex = svc::ipc::MessageBuffer::GetSpecialDataIndex(InMessageHeader, InSpecialHeader) + (HasProcessId ? sizeof(u64) / sizeof(u32) : 0);
|
||||
static constexpr auto InMessageBufferIndex = svc::ipc::MessageBuffer::GetMapAliasDescriptorIndex(InMessageHeader, InSpecialHeader);
|
||||
static constexpr auto InMessageRawDataIndex = svc::ipc::MessageBuffer::GetRawDataIndex(InMessageHeader, InSpecialHeader);
|
||||
static constexpr auto InMessageProcessIdIndex = MessageBuffer::GetSpecialDataIndex(InMessageHeader, InSpecialHeader);
|
||||
static constexpr auto InMessageHandleIndex = MessageBuffer::GetSpecialDataIndex(InMessageHeader, InSpecialHeader) + (HasProcessId ? sizeof(u64) / sizeof(u32) : 0);
|
||||
static constexpr auto InMessageBufferIndex = MessageBuffer::GetMapAliasDescriptorIndex(InMessageHeader, InSpecialHeader);
|
||||
static constexpr auto InMessageRawDataIndex = MessageBuffer::GetRawDataIndex(InMessageHeader, InSpecialHeader);
|
||||
|
||||
static constexpr bool HasOutSpecialHeader = NumOutHandles > 0;
|
||||
|
||||
static constexpr svc::ipc::MessageBuffer::MessageHeader OutMessageHeader{CommandId, HasOutSpecialHeader, 0, 0, 0, 0, (OutDataSize / sizeof(u32)) + 1, 0};
|
||||
static constexpr svc::ipc::MessageBuffer::SpecialHeader OutSpecialHeader{false, NumOutCopyHandles, NumOutMoveHandles, HasOutSpecialHeader};
|
||||
static constexpr MessageBuffer::MessageHeader OutMessageHeader{CommandId, HasOutSpecialHeader, 0, 0, 0, 0, (OutDataSize / sizeof(u32)) + 1, 0};
|
||||
static constexpr MessageBuffer::SpecialHeader OutSpecialHeader{false, NumOutCopyHandles, NumOutMoveHandles, HasOutSpecialHeader};
|
||||
|
||||
static constexpr auto OutMessageHandleIndex = svc::ipc::MessageBuffer::GetSpecialDataIndex(OutMessageHeader, OutSpecialHeader);
|
||||
static constexpr auto OutMessageResultIndex = svc::ipc::MessageBuffer::GetRawDataIndex(OutMessageHeader, OutSpecialHeader);
|
||||
static constexpr auto OutMessageHandleIndex = MessageBuffer::GetSpecialDataIndex(OutMessageHeader, OutSpecialHeader);
|
||||
static constexpr auto OutMessageResultIndex = MessageBuffer::GetRawDataIndex(OutMessageHeader, OutSpecialHeader);
|
||||
static constexpr auto OutMessageRawDataIndex = OutMessageResultIndex + 1;
|
||||
|
||||
static constexpr size_t InMessageTotalSize = (InMessageRawDataIndex * sizeof(u32)) + InDataSize;
|
||||
@@ -410,7 +411,7 @@ namespace ams::tipc::impl {
|
||||
return reinterpret_cast<uintptr_t>(data + Offset);
|
||||
}
|
||||
|
||||
constexpr ALWAYS_INLINE void CopyTo(const svc::ipc::MessageBuffer &buffer) const {
|
||||
constexpr ALWAYS_INLINE void CopyTo(const MessageBuffer &buffer) const {
|
||||
if constexpr (Size > 0) {
|
||||
buffer.SetRawArray(OutIndex, data, Size);
|
||||
}
|
||||
@@ -423,24 +424,24 @@ namespace ams::tipc::impl {
|
||||
static constexpr size_t NumMove = _NumMove;
|
||||
static constexpr size_t NumCopy = _NumCopy;
|
||||
private:
|
||||
os::NativeHandle move_handles[NumMove];
|
||||
os::NativeHandle copy_handles[NumCopy];
|
||||
tipc::NativeHandle move_handles[NumMove];
|
||||
tipc::NativeHandle copy_handles[NumCopy];
|
||||
public:
|
||||
ALWAYS_INLINE OutHandleHolder() { /* ... */ }
|
||||
|
||||
template<size_t Index>
|
||||
constexpr ALWAYS_INLINE os::NativeHandle *GetMoveHandlePointer() {
|
||||
constexpr ALWAYS_INLINE tipc::NativeHandle *GetMoveHandlePointer() {
|
||||
static_assert(Index < NumMove, "Index < NumMove");
|
||||
return move_handles + Index;
|
||||
}
|
||||
|
||||
template<size_t Index>
|
||||
constexpr ALWAYS_INLINE os::NativeHandle *GetCopyHandlePointer() {
|
||||
constexpr ALWAYS_INLINE tipc::NativeHandle *GetCopyHandlePointer() {
|
||||
static_assert(Index < NumCopy, "Index < NumCopy");
|
||||
return copy_handles + Index;
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void CopyTo(const svc::ipc::MessageBuffer &buffer) const {
|
||||
ALWAYS_INLINE void CopyTo(const MessageBuffer &buffer) const {
|
||||
#define _TIPC_OUT_HANDLE_HOLDER_WRITE_COPY_HANDLE(n) do { if constexpr (NumCopy > n) { buffer.SetHandle(OutIndex + n, copy_handles[n]); } } while (0)
|
||||
_TIPC_OUT_HANDLE_HOLDER_WRITE_COPY_HANDLE(0);
|
||||
_TIPC_OUT_HANDLE_HOLDER_WRITE_COPY_HANDLE(1);
|
||||
@@ -475,7 +476,7 @@ namespace ams::tipc::impl {
|
||||
using OutRawHolderType = OutRawHolder<CommandMeta::OutDataSize, CommandMeta::OutDataAlign, CommandMeta::OutMessageRawDataIndex>;
|
||||
using OutHandleHolderType = OutHandleHolder<CommandMeta::NumOutMoveHandles, CommandMeta::NumOutCopyHandles, CommandMeta::OutMessageHandleIndex>;
|
||||
private:
|
||||
static constexpr u64 GetMessageHeaderForCheck(const svc::ipc::MessageBuffer::MessageHeader &header) {
|
||||
static constexpr u64 GetMessageHeaderForCheck(const MessageBuffer::MessageHeader &header) {
|
||||
using Value = util::BitPack32::Field<0, BITSIZEOF(util::BitPack32)>;
|
||||
|
||||
const util::BitPack32 *data = header.GetData();
|
||||
@@ -485,7 +486,7 @@ namespace ams::tipc::impl {
|
||||
return static_cast<u64>(lower) | (static_cast<u64>(upper) << BITSIZEOF(u32));
|
||||
}
|
||||
|
||||
static constexpr u32 GetSpecialHeaderForCheck(const svc::ipc::MessageBuffer::SpecialHeader &header) {
|
||||
static constexpr u32 GetSpecialHeaderForCheck(const MessageBuffer::SpecialHeader &header) {
|
||||
using Value = util::BitPack32::Field<0, BITSIZEOF(util::BitPack32)>;
|
||||
|
||||
return header.GetHeader()->Get<Value>();
|
||||
@@ -493,7 +494,7 @@ namespace ams::tipc::impl {
|
||||
|
||||
/* Argument deserialization. */
|
||||
template<size_t Index, typename T = typename std::tuple_element<Index, ArgsType>::type>
|
||||
static ALWAYS_INLINE typename std::tuple_element<Index, ArgsType>::type DeserializeArgumentImpl(const svc::ipc::MessageBuffer &message_buffer, const OutRawHolderType &out_raw_holder, OutHandleHolderType &out_handles_holder) {
|
||||
static ALWAYS_INLINE typename std::tuple_element<Index, ArgsType>::type DeserializeArgumentImpl(const MessageBuffer &message_buffer, const OutRawHolderType &out_raw_holder, OutHandleHolderType &out_handles_holder) {
|
||||
constexpr auto Info = CommandMeta::ArgumentSerializationInfos[Index];
|
||||
if constexpr (Info.arg_type == ArgumentType::InData) {
|
||||
/* New in rawdata. */
|
||||
@@ -524,12 +525,12 @@ namespace ams::tipc::impl {
|
||||
} else if constexpr (Info.arg_type == ArgumentType::OutHandle) {
|
||||
/* New OutHandle. */
|
||||
if constexpr (std::same_as<T, tipc::OutMoveHandle>) {
|
||||
os::NativeHandle * const ptr = out_handles_holder.template GetMoveHandlePointer<Info.out_move_handle_index>();
|
||||
*ptr = os::InvalidNativeHandle;
|
||||
tipc::NativeHandle * const ptr = out_handles_holder.template GetMoveHandlePointer<Info.out_move_handle_index>();
|
||||
*ptr = tipc::InvalidNativeHandle;
|
||||
return T(ptr);
|
||||
} else if constexpr (std::same_as<T, tipc::OutCopyHandle>) {
|
||||
os::NativeHandle * const ptr = out_handles_holder.template GetCopyHandlePointer<Info.out_copy_handle_index>();
|
||||
*ptr = os::InvalidNativeHandle;
|
||||
tipc::NativeHandle * const ptr = out_handles_holder.template GetCopyHandlePointer<Info.out_copy_handle_index>();
|
||||
*ptr = tipc::InvalidNativeHandle;
|
||||
return T(ptr);
|
||||
} else {
|
||||
static_assert(!std::is_same<T, T>::value, "Invalid OutHandle kind");
|
||||
@@ -537,19 +538,19 @@ namespace ams::tipc::impl {
|
||||
} else if constexpr (Info.arg_type == ArgumentType::Buffer) {
|
||||
/* NOTE: There are currently no tipc commands which use buffers-with-attributes */
|
||||
/* If these are added (e.g., NonSecure buffers), implement checking here? */
|
||||
constexpr size_t MapAliasDescriptorSize = svc::ipc::MessageBuffer::MapAliasDescriptor::GetDataSize();
|
||||
constexpr size_t MapAliasDescriptorSize = MessageBuffer::MapAliasDescriptor::GetDataSize();
|
||||
|
||||
if constexpr (Info.is_send_buffer) {
|
||||
/* Input send buffer. */
|
||||
constexpr auto BufferIndex = CommandMeta::InMessageBufferIndex + (Info.send_map_alias_index * MapAliasDescriptorSize / sizeof(util::BitPack32));
|
||||
|
||||
const svc::ipc::MessageBuffer::MapAliasDescriptor descriptor(message_buffer, BufferIndex);
|
||||
const MessageBuffer::MapAliasDescriptor descriptor(message_buffer, BufferIndex);
|
||||
return T(descriptor.GetAddress(), descriptor.GetSize());
|
||||
} else {
|
||||
/* Input receive buffer. */
|
||||
constexpr auto BufferIndex = CommandMeta::InMessageBufferIndex + ((CommandMeta::NumInBuffers + Info.recv_map_alias_index) * MapAliasDescriptorSize / sizeof(util::BitPack32));
|
||||
|
||||
const svc::ipc::MessageBuffer::MapAliasDescriptor descriptor(message_buffer, BufferIndex);
|
||||
const MessageBuffer::MapAliasDescriptor descriptor(message_buffer, BufferIndex);
|
||||
return T(descriptor.GetAddress(), descriptor.GetSize());
|
||||
}
|
||||
} else if constexpr (Info.arg_type == ArgumentType::ProcessId) {
|
||||
@@ -559,7 +560,7 @@ namespace ams::tipc::impl {
|
||||
}
|
||||
}
|
||||
public:
|
||||
static ALWAYS_INLINE Result ValidateCommandFormat(const svc::ipc::MessageBuffer &message_buffer) {
|
||||
static ALWAYS_INLINE Result ValidateCommandFormat(const MessageBuffer &message_buffer) {
|
||||
/* Validate the message header. */
|
||||
constexpr auto ExpectedMessageHeader = GetMessageHeaderForCheck(CommandMeta::InMessageHeader);
|
||||
R_UNLESS(message_buffer.Get64(0) == ExpectedMessageHeader, tipc::ResultInvalidMessageFormat());
|
||||
@@ -567,7 +568,7 @@ namespace ams::tipc::impl {
|
||||
/* Validate the special header. */
|
||||
if constexpr (CommandMeta::HasInSpecialHeader) {
|
||||
constexpr auto ExpectedSpecialHeader = GetSpecialHeaderForCheck(CommandMeta::InSpecialHeader);
|
||||
constexpr auto SpecialHeaderIndex = svc::ipc::MessageBuffer::MessageHeader::GetDataSize() / sizeof(util::BitPack32);
|
||||
constexpr auto SpecialHeaderIndex = MessageBuffer::MessageHeader::GetDataSize() / sizeof(util::BitPack32);
|
||||
R_UNLESS(message_buffer.Get32(SpecialHeaderIndex) == ExpectedSpecialHeader, tipc::ResultInvalidMessageFormat());
|
||||
}
|
||||
|
||||
@@ -575,11 +576,11 @@ namespace ams::tipc::impl {
|
||||
}
|
||||
|
||||
template<size_t Ix>
|
||||
static ALWAYS_INLINE auto DeserializeArgument(const svc::ipc::MessageBuffer &message_buffer, const OutRawHolderType &out_raw_holder, OutHandleHolderType &out_handles_holder) {
|
||||
static ALWAYS_INLINE auto DeserializeArgument(const MessageBuffer &message_buffer, const OutRawHolderType &out_raw_holder, OutHandleHolderType &out_handles_holder) {
|
||||
return DeserializeArgumentImpl<Ix>(message_buffer, out_raw_holder, out_handles_holder);
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE void SerializeResults(const svc::ipc::MessageBuffer &message_buffer, const Result &result, const OutRawHolderType &out_raw_holder, const OutHandleHolderType &out_handles_holder) {
|
||||
static ALWAYS_INLINE void SerializeResults(const MessageBuffer &message_buffer, const Result &result, const OutRawHolderType &out_raw_holder, const OutHandleHolderType &out_handles_holder) {
|
||||
/* Set output headers. */
|
||||
message_buffer.Set(CommandMeta::OutMessageHeader);
|
||||
if constexpr (CommandMeta::HasOutSpecialHeader) {
|
||||
@@ -607,7 +608,7 @@ namespace ams::tipc::impl {
|
||||
};
|
||||
|
||||
template<u16 _CommmandId, auto ServiceCommandImpl, typename ClassType>
|
||||
constexpr ALWAYS_INLINE Result InvokeServiceCommandImpl(ClassType *object, const svc::ipc::MessageBuffer &message_buffer) {
|
||||
constexpr ALWAYS_INLINE Result InvokeServiceCommandImpl(ClassType *object, const MessageBuffer &message_buffer) {
|
||||
using Return = decltype(FunctionTraits::GetReturnImpl(ServiceCommandImpl));
|
||||
using TrueArgumentsTuple = decltype(FunctionTraits::GetArgumentsImpl(ServiceCommandImpl));
|
||||
|
||||
@@ -641,3 +642,97 @@ namespace ams::tipc::impl {
|
||||
}
|
||||
|
||||
}
|
||||
#elif defined(ATMOSPHERE_OS_WINDOWS)
|
||||
namespace ams::tipc::impl {
|
||||
|
||||
template<u16 _CommandId, typename ArgumentsTuple>
|
||||
struct CommandMetaInfo;
|
||||
|
||||
template<u16 _CommandId, typename... Arguments>
|
||||
struct CommandMetaInfo<_CommandId, std::tuple<Arguments...>> {
|
||||
public:
|
||||
static constexpr size_t InMessageTotalSize = 0x40; /* TODO */
|
||||
static constexpr size_t OutMessageTotalSize = 0x40; /* TODO */
|
||||
};
|
||||
|
||||
template<typename CommandMeta>
|
||||
class CommandProcessor {
|
||||
public:
|
||||
static ALWAYS_INLINE Result ValidateCommandFormat(const MessageBuffer &) {
|
||||
AMS_ABORT("TODO");
|
||||
}
|
||||
};
|
||||
|
||||
template<u16 _CommmandId, auto ServiceCommandImpl, typename ClassType>
|
||||
ALWAYS_INLINE Result InvokeServiceCommandImpl(ClassType *object, const MessageBuffer &message_buffer) {
|
||||
/* TODO: Is some kind of emulated serialization interesting/desirable? */
|
||||
/* TIPC is generally a huge TODO. */
|
||||
AMS_UNUSED(object, message_buffer);
|
||||
AMS_ABORT("TIPC serialization not currently supported on Windows.");
|
||||
}
|
||||
|
||||
}
|
||||
#elif defined(ATMOSPHERE_OS_LINUX)
|
||||
namespace ams::tipc::impl {
|
||||
|
||||
template<u16 _CommandId, typename ArgumentsTuple>
|
||||
struct CommandMetaInfo;
|
||||
|
||||
template<u16 _CommandId, typename... Arguments>
|
||||
struct CommandMetaInfo<_CommandId, std::tuple<Arguments...>> {
|
||||
public:
|
||||
static constexpr size_t InMessageTotalSize = 0x40; /* TODO */
|
||||
static constexpr size_t OutMessageTotalSize = 0x40; /* TODO */
|
||||
};
|
||||
|
||||
template<typename CommandMeta>
|
||||
class CommandProcessor {
|
||||
public:
|
||||
static ALWAYS_INLINE Result ValidateCommandFormat(const MessageBuffer &) {
|
||||
AMS_ABORT("TODO");
|
||||
}
|
||||
};
|
||||
|
||||
template<u16 _CommmandId, auto ServiceCommandImpl, typename ClassType>
|
||||
ALWAYS_INLINE Result InvokeServiceCommandImpl(ClassType *object, const MessageBuffer &message_buffer) {
|
||||
/* TODO: Is some kind of emulated serialization interesting/desirable? */
|
||||
/* TIPC is generally a huge TODO. */
|
||||
AMS_UNUSED(object, message_buffer);
|
||||
AMS_ABORT("TIPC serialization not currently supported on Linux.");
|
||||
}
|
||||
|
||||
}
|
||||
#elif defined(ATMOSPHERE_OS_MACOS)
|
||||
namespace ams::tipc::impl {
|
||||
|
||||
template<u16 _CommandId, typename ArgumentsTuple>
|
||||
struct CommandMetaInfo;
|
||||
|
||||
template<u16 _CommandId, typename... Arguments>
|
||||
struct CommandMetaInfo<_CommandId, std::tuple<Arguments...>> {
|
||||
public:
|
||||
static constexpr size_t InMessageTotalSize = 0x40; /* TODO */
|
||||
static constexpr size_t OutMessageTotalSize = 0x40; /* TODO */
|
||||
};
|
||||
|
||||
template<typename CommandMeta>
|
||||
class CommandProcessor {
|
||||
public:
|
||||
static ALWAYS_INLINE Result ValidateCommandFormat(const MessageBuffer &) {
|
||||
AMS_ABORT("TODO");
|
||||
}
|
||||
};
|
||||
|
||||
template<u16 _CommmandId, auto ServiceCommandImpl, typename ClassType>
|
||||
ALWAYS_INLINE Result InvokeServiceCommandImpl(ClassType *object, const MessageBuffer &message_buffer) {
|
||||
/* TODO: Is some kind of emulated serialization interesting/desirable? */
|
||||
/* TIPC is generally a huge TODO. */
|
||||
AMS_UNUSED(object, message_buffer);
|
||||
AMS_ABORT("TIPC serialization not currently supported on macOS.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
#error "Unknown OS for tipc Command serialization."
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 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/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <vapours.hpp>
|
||||
|
||||
#if defined(ATMOSPHERE_OS_HORIZON)
|
||||
#include <stratosphere/tipc/impl/tipc_impl_message_api.os.horizon.hpp>
|
||||
#elif defined(ATMOSPHERE_OS_WINDOWS)
|
||||
#include <stratosphere/tipc/impl/tipc_impl_message_api.os.windows.hpp>
|
||||
#elif defined(ATMOSPHERE_OS_LINUX)
|
||||
#include <stratosphere/tipc/impl/tipc_impl_message_api.os.linux.hpp>
|
||||
#elif defined(ATMOSPHERE_OS_MACOS)
|
||||
#include <stratosphere/tipc/impl/tipc_impl_message_api.os.macos.hpp>
|
||||
#else
|
||||
#error "Unknown OS for tipc message impl"
|
||||
#endif
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 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/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <vapours.hpp>
|
||||
#include <stratosphere/tipc/tipc_common.hpp>
|
||||
#include <stratosphere/tipc/tipc_message_types.hpp>
|
||||
|
||||
namespace ams::tipc::impl {
|
||||
|
||||
inline void Reply(tipc::NativeHandle reply_target) {
|
||||
/* Perform the reply. */
|
||||
s32 dummy;
|
||||
R_TRY_CATCH(svc::ReplyAndReceive(std::addressof(dummy), nullptr, 0, reply_target, 0)) {
|
||||
R_CATCH(svc::ResultTimedOut) {
|
||||
/* Timing out is acceptable. */
|
||||
}
|
||||
R_CATCH(svc::ResultSessionClosed) {
|
||||
/* It's okay if we couldn't reply to a closed session. */
|
||||
}
|
||||
} R_END_TRY_CATCH_WITH_ABORT_UNLESS;
|
||||
}
|
||||
|
||||
ALWAYS_INLINE Result CloseHandle(tipc::NativeHandle handle) {
|
||||
return svc::CloseHandle(handle);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE Result CreateSession(tipc::NativeHandle *out_server_session_handle, tipc::NativeHandle *out_client_session_handle, bool is_light, uintptr_t name) {
|
||||
return svc::CreateSession(out_server_session_handle, out_client_session_handle, is_light, name);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE Result AcceptSession(tipc::NativeHandle *out_handle, tipc::NativeHandle port) {
|
||||
return svc::AcceptSession(out_handle, port);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 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/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <vapours.hpp>
|
||||
#include <stratosphere/tipc/tipc_common.hpp>
|
||||
#include <stratosphere/tipc/tipc_message_types.hpp>
|
||||
|
||||
namespace ams::tipc::impl {
|
||||
|
||||
inline void Reply(tipc::NativeHandle reply_target) {
|
||||
AMS_UNUSED(reply_target);
|
||||
AMS_ABORT("TODO: tipc Linux Reply");
|
||||
}
|
||||
|
||||
ALWAYS_INLINE Result CloseHandle(tipc::NativeHandle handle) {
|
||||
AMS_UNUSED(handle);
|
||||
AMS_ABORT("TODO: tipc Linux CloseHandle");
|
||||
}
|
||||
|
||||
ALWAYS_INLINE Result CreateSession(tipc::NativeHandle *out_server_session_handle, tipc::NativeHandle *out_client_session_handle, bool is_light, uintptr_t name) {
|
||||
AMS_UNUSED(out_server_session_handle, out_client_session_handle, is_light, name);
|
||||
AMS_ABORT("TODO: tipc Linux CreateSession");
|
||||
}
|
||||
|
||||
ALWAYS_INLINE Result AcceptSession(tipc::NativeHandle *out_handle, tipc::NativeHandle port) {
|
||||
AMS_UNUSED(out_handle, port);
|
||||
AMS_ABORT("TODO: tipc Linux AcceptSession");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 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/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <vapours.hpp>
|
||||
#include <stratosphere/tipc/tipc_common.hpp>
|
||||
#include <stratosphere/tipc/tipc_message_types.hpp>
|
||||
|
||||
namespace ams::tipc::impl {
|
||||
|
||||
inline void Reply(tipc::NativeHandle reply_target) {
|
||||
AMS_UNUSED(reply_target);
|
||||
AMS_ABORT("TODO: tipc macOS Reply");
|
||||
}
|
||||
|
||||
ALWAYS_INLINE Result CloseHandle(tipc::NativeHandle handle) {
|
||||
AMS_UNUSED(handle);
|
||||
AMS_ABORT("TODO: tipc macOS CloseHandle");
|
||||
}
|
||||
|
||||
ALWAYS_INLINE Result CreateSession(tipc::NativeHandle *out_server_session_handle, tipc::NativeHandle *out_client_session_handle, bool is_light, uintptr_t name) {
|
||||
AMS_UNUSED(out_server_session_handle, out_client_session_handle, is_light, name);
|
||||
AMS_ABORT("TODO: tipc macOS CreateSession");
|
||||
}
|
||||
|
||||
ALWAYS_INLINE Result AcceptSession(tipc::NativeHandle *out_handle, tipc::NativeHandle port) {
|
||||
AMS_UNUSED(out_handle, port);
|
||||
AMS_ABORT("TODO: tipc macOS AcceptSession");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 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/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <vapours.hpp>
|
||||
#include <stratosphere/tipc/tipc_common.hpp>
|
||||
#include <stratosphere/tipc/tipc_message_types.hpp>
|
||||
|
||||
namespace ams::tipc::impl {
|
||||
|
||||
inline void Reply(tipc::NativeHandle reply_target) {
|
||||
AMS_UNUSED(reply_target);
|
||||
AMS_ABORT("TODO: tipc Windows Reply");
|
||||
}
|
||||
|
||||
ALWAYS_INLINE Result CloseHandle(tipc::NativeHandle handle) {
|
||||
AMS_UNUSED(handle);
|
||||
AMS_ABORT("TODO: tipc Windows CloseHandle");
|
||||
}
|
||||
|
||||
ALWAYS_INLINE Result CreateSession(tipc::NativeHandle *out_server_session_handle, tipc::NativeHandle *out_client_session_handle, bool is_light, uintptr_t name) {
|
||||
AMS_UNUSED(out_server_session_handle, out_client_session_handle, is_light, name);
|
||||
AMS_ABORT("TODO: tipc Windows CreateSession");
|
||||
}
|
||||
|
||||
ALWAYS_INLINE Result AcceptSession(tipc::NativeHandle *out_handle, tipc::NativeHandle port) {
|
||||
AMS_UNUSED(out_handle, port);
|
||||
AMS_ABORT("TODO: tipc Windows AcceptSession");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -60,8 +60,8 @@ namespace ams::tipc {
|
||||
constexpr ALWAYS_INLINE InBufferBase(const tipc::PointerAndSize &pas) : BaseType(pas) { /* ... */ }
|
||||
constexpr ALWAYS_INLINE InBufferBase(uintptr_t ptr, size_t sz) : BaseType(ptr, sz) { /* ... */ }
|
||||
|
||||
constexpr ALWAYS_INLINE InBufferBase(const void *ptr, size_t sz) : BaseType(reinterpret_cast<uintptr_t>(ptr), sz) { /* ... */ }
|
||||
constexpr ALWAYS_INLINE InBufferBase(const u8 *ptr, size_t sz) : BaseType(reinterpret_cast<uintptr_t>(ptr), sz) { /* ... */ }
|
||||
ALWAYS_INLINE InBufferBase(const void *ptr, size_t sz) : BaseType(reinterpret_cast<uintptr_t>(ptr), sz) { /* ... */ }
|
||||
ALWAYS_INLINE InBufferBase(const u8 *ptr, size_t sz) : BaseType(reinterpret_cast<uintptr_t>(ptr), sz) { /* ... */ }
|
||||
};
|
||||
|
||||
class OutBufferBase : public BufferBase {
|
||||
@@ -74,8 +74,8 @@ namespace ams::tipc {
|
||||
constexpr ALWAYS_INLINE OutBufferBase(const tipc::PointerAndSize &pas) : BaseType(pas) { /* ... */ }
|
||||
constexpr ALWAYS_INLINE OutBufferBase(uintptr_t ptr, size_t sz) : BaseType(ptr, sz) { /* ... */ }
|
||||
|
||||
constexpr ALWAYS_INLINE OutBufferBase(void *ptr, size_t sz) : BaseType(reinterpret_cast<uintptr_t>(ptr), sz) { /* ... */ }
|
||||
constexpr ALWAYS_INLINE OutBufferBase(u8 *ptr, size_t sz) : BaseType(reinterpret_cast<uintptr_t>(ptr), sz) { /* ... */ }
|
||||
ALWAYS_INLINE OutBufferBase(void *ptr, size_t sz) : BaseType(reinterpret_cast<uintptr_t>(ptr), sz) { /* ... */ }
|
||||
ALWAYS_INLINE OutBufferBase(u8 *ptr, size_t sz) : BaseType(reinterpret_cast<uintptr_t>(ptr), sz) { /* ... */ }
|
||||
};
|
||||
|
||||
template<u32 ExtraAttributes = 0>
|
||||
@@ -89,10 +89,10 @@ namespace ams::tipc {
|
||||
constexpr ALWAYS_INLINE InBufferImpl(const tipc::PointerAndSize &pas) : BaseType(pas) { /* ... */ }
|
||||
constexpr ALWAYS_INLINE InBufferImpl(uintptr_t ptr, size_t sz) : BaseType(ptr, sz) { /* ... */ }
|
||||
|
||||
constexpr ALWAYS_INLINE InBufferImpl(const void *ptr, size_t sz) : BaseType(reinterpret_cast<uintptr_t>(ptr), sz) { /* ... */ }
|
||||
constexpr ALWAYS_INLINE InBufferImpl(const u8 *ptr, size_t sz) : BaseType(reinterpret_cast<uintptr_t>(ptr), sz) { /* ... */ }
|
||||
ALWAYS_INLINE InBufferImpl(const void *ptr, size_t sz) : BaseType(reinterpret_cast<uintptr_t>(ptr), sz) { /* ... */ }
|
||||
ALWAYS_INLINE InBufferImpl(const u8 *ptr, size_t sz) : BaseType(reinterpret_cast<uintptr_t>(ptr), sz) { /* ... */ }
|
||||
|
||||
constexpr ALWAYS_INLINE const u8 *GetPointer() const {
|
||||
ALWAYS_INLINE const u8 *GetPointer() const {
|
||||
return reinterpret_cast<const u8 *>(this->GetAddressImpl());
|
||||
}
|
||||
|
||||
@@ -112,10 +112,10 @@ namespace ams::tipc {
|
||||
constexpr ALWAYS_INLINE OutBufferImpl(const tipc::PointerAndSize &pas) : BaseType(pas) { /* ... */ }
|
||||
constexpr ALWAYS_INLINE OutBufferImpl(uintptr_t ptr, size_t sz) : BaseType(ptr, sz) { /* ... */ }
|
||||
|
||||
constexpr ALWAYS_INLINE OutBufferImpl(void *ptr, size_t sz) : BaseType(reinterpret_cast<uintptr_t>(ptr), sz) { /* ... */ }
|
||||
constexpr ALWAYS_INLINE OutBufferImpl(u8 *ptr, size_t sz) : BaseType(reinterpret_cast<uintptr_t>(ptr), sz) { /* ... */ }
|
||||
ALWAYS_INLINE OutBufferImpl(void *ptr, size_t sz) : BaseType(reinterpret_cast<uintptr_t>(ptr), sz) { /* ... */ }
|
||||
ALWAYS_INLINE OutBufferImpl(u8 *ptr, size_t sz) : BaseType(reinterpret_cast<uintptr_t>(ptr), sz) { /* ... */ }
|
||||
|
||||
constexpr ALWAYS_INLINE u8 *GetPointer() const {
|
||||
ALWAYS_INLINE u8 *GetPointer() const {
|
||||
return reinterpret_cast<u8 *>(this->GetAddressImpl());
|
||||
}
|
||||
|
||||
@@ -134,9 +134,9 @@ namespace ams::tipc {
|
||||
constexpr ALWAYS_INLINE InArrayImpl(const tipc::PointerAndSize &pas) : BaseType(pas) { /* ... */ }
|
||||
constexpr ALWAYS_INLINE InArrayImpl(uintptr_t ptr, size_t sz) : BaseType(ptr, sz) { /* ... */ }
|
||||
|
||||
constexpr ALWAYS_INLINE InArrayImpl(const T *ptr, size_t num_elements) : BaseType(reinterpret_cast<uintptr_t>(ptr), num_elements * sizeof(T)) { /* ... */ }
|
||||
ALWAYS_INLINE InArrayImpl(const T *ptr, size_t num_elements) : BaseType(reinterpret_cast<uintptr_t>(ptr), num_elements * sizeof(T)) { /* ... */ }
|
||||
|
||||
constexpr ALWAYS_INLINE const T *GetPointer() const {
|
||||
ALWAYS_INLINE const T *GetPointer() const {
|
||||
return reinterpret_cast<const T *>(this->GetAddressImpl());
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ namespace ams::tipc {
|
||||
return this->GetSizeImpl<T>();
|
||||
}
|
||||
|
||||
constexpr ALWAYS_INLINE const T &operator[](size_t i) const {
|
||||
ALWAYS_INLINE const T &operator[](size_t i) const {
|
||||
return this->GetPointer()[i];
|
||||
}
|
||||
|
||||
@@ -167,9 +167,9 @@ namespace ams::tipc {
|
||||
constexpr ALWAYS_INLINE OutArrayImpl(const tipc::PointerAndSize &pas) : BaseType(pas) { /* ... */ }
|
||||
constexpr ALWAYS_INLINE OutArrayImpl(uintptr_t ptr, size_t sz) : BaseType(ptr, sz) { /* ... */ }
|
||||
|
||||
constexpr ALWAYS_INLINE OutArrayImpl(T *ptr, size_t num_elements) : BaseType(reinterpret_cast<uintptr_t>(ptr), num_elements * sizeof(T)) { /* ... */ }
|
||||
ALWAYS_INLINE OutArrayImpl(T *ptr, size_t num_elements) : BaseType(reinterpret_cast<uintptr_t>(ptr), num_elements * sizeof(T)) { /* ... */ }
|
||||
|
||||
constexpr ALWAYS_INLINE T *GetPointer() const {
|
||||
ALWAYS_INLINE T *GetPointer() const {
|
||||
return reinterpret_cast<T *>(this->GetAddressImpl());
|
||||
}
|
||||
|
||||
@@ -177,7 +177,7 @@ namespace ams::tipc {
|
||||
return this->GetSizeImpl<T>();
|
||||
}
|
||||
|
||||
constexpr ALWAYS_INLINE T &operator[](size_t i) const {
|
||||
ALWAYS_INLINE T &operator[](size_t i) const {
|
||||
return this->GetPointer()[i];
|
||||
}
|
||||
|
||||
|
||||
@@ -17,4 +17,5 @@
|
||||
#include <vapours.hpp>
|
||||
#include <stratosphere/ams.hpp>
|
||||
#include <stratosphere/os.hpp>
|
||||
#include <stratosphere/sm/sm_types.hpp>
|
||||
#include <stratosphere/sm/sm_types.hpp>
|
||||
#include <stratosphere/tipc/tipc_message_types.hpp>
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
#pragma once
|
||||
#include <vapours.hpp>
|
||||
#include <stratosphere/tipc/tipc_message_types.hpp>
|
||||
#include <stratosphere/tipc/tipc_object_holder.hpp>
|
||||
#include <stratosphere/tipc/tipc_service_object_base.hpp>
|
||||
|
||||
@@ -56,7 +57,7 @@ namespace ams::tipc {
|
||||
|
||||
~DeferrableBaseImpl();
|
||||
|
||||
ALWAYS_INLINE void SetDeferralManager(DeferralManagerBase *manager, os::NativeHandle reply_target, ServiceObjectBase *object) {
|
||||
ALWAYS_INLINE void SetDeferralManager(DeferralManagerBase *manager, tipc::NativeHandle reply_target, ServiceObjectBase *object) {
|
||||
m_deferral_manager = manager;
|
||||
m_object_holder.InitializeForDeferralManager(reply_target, object);
|
||||
}
|
||||
@@ -68,7 +69,7 @@ namespace ams::tipc {
|
||||
template<IsResumeKey ResumeKey>
|
||||
ALWAYS_INLINE void RegisterRetry(ResumeKey key) {
|
||||
m_resume_key = ConvertToInternalResumeKey(key);
|
||||
std::memcpy(m_message_buffer_base, svc::ipc::GetMessageBuffer(), m_message_buffer_size);
|
||||
std::memcpy(m_message_buffer_base, tipc::GetMessageBuffer(), m_message_buffer_size);
|
||||
}
|
||||
|
||||
template<IsResumeKey ResumeKey, typename F>
|
||||
@@ -86,7 +87,7 @@ namespace ams::tipc {
|
||||
m_resume_key = 0;
|
||||
|
||||
/* Restore message buffer. */
|
||||
std::memcpy(svc::ipc::GetMessageBuffer(), m_message_buffer_base, m_message_buffer_size);
|
||||
std::memcpy(tipc::GetMessageBuffer(), m_message_buffer_base, m_message_buffer_size);
|
||||
|
||||
/* Process the request. */
|
||||
return port_manager->ProcessDeferredRequest(m_object_holder);
|
||||
@@ -145,12 +146,11 @@ namespace ams::tipc {
|
||||
public:
|
||||
ALWAYS_INLINE DeferralManagerBase() : m_object_count(0) { /* ... */ }
|
||||
|
||||
void AddObject(DeferrableBaseImpl &object, os::NativeHandle reply_target, ServiceObjectBase *service_object) {
|
||||
void AddObject(DeferrableBaseImpl &object, tipc::NativeHandle reply_target, ServiceObjectBase *service_object) {
|
||||
/* Set ourselves as the manager for the object. */
|
||||
object.SetDeferralManager(this, reply_target, service_object);
|
||||
|
||||
/* Add the object to our entries. */
|
||||
AMS_ASSERT(m_object_count < N);
|
||||
m_objects_base[m_object_count++] = std::addressof(object);
|
||||
}
|
||||
|
||||
|
||||
@@ -34,28 +34,28 @@ namespace ams::tipc {
|
||||
template<>
|
||||
class Out<CopyHandle> {
|
||||
private:
|
||||
os::NativeHandle * const m_ptr;
|
||||
tipc::NativeHandle * const m_ptr;
|
||||
public:
|
||||
ALWAYS_INLINE Out(os::NativeHandle *p) : m_ptr(p) { /* ... */ }
|
||||
ALWAYS_INLINE Out(tipc::NativeHandle *p) : m_ptr(p) { /* ... */ }
|
||||
|
||||
ALWAYS_INLINE void SetValue(os::NativeHandle v) const {
|
||||
ALWAYS_INLINE void SetValue(tipc::NativeHandle v) const {
|
||||
*m_ptr = v;
|
||||
}
|
||||
|
||||
ALWAYS_INLINE const os::NativeHandle &GetValue() const {
|
||||
ALWAYS_INLINE const tipc::NativeHandle &GetValue() const {
|
||||
return *m_ptr;
|
||||
}
|
||||
|
||||
ALWAYS_INLINE os::NativeHandle *GetPointer() const {
|
||||
ALWAYS_INLINE tipc::NativeHandle *GetPointer() const {
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
/* Convenience operators. */
|
||||
ALWAYS_INLINE os::NativeHandle &operator*() const {
|
||||
ALWAYS_INLINE tipc::NativeHandle &operator*() const {
|
||||
return *m_ptr;
|
||||
}
|
||||
|
||||
ALWAYS_INLINE os::NativeHandle *operator->() const {
|
||||
ALWAYS_INLINE tipc::NativeHandle *operator->() const {
|
||||
return m_ptr;
|
||||
}
|
||||
};
|
||||
@@ -63,28 +63,28 @@ namespace ams::tipc {
|
||||
template<>
|
||||
class Out<MoveHandle> {
|
||||
private:
|
||||
os::NativeHandle * const m_ptr;
|
||||
tipc::NativeHandle * const m_ptr;
|
||||
public:
|
||||
ALWAYS_INLINE Out(os::NativeHandle *p) : m_ptr(p) { /* ... */ }
|
||||
ALWAYS_INLINE Out(tipc::NativeHandle *p) : m_ptr(p) { /* ... */ }
|
||||
|
||||
ALWAYS_INLINE void SetValue(os::NativeHandle v) const {
|
||||
ALWAYS_INLINE void SetValue(tipc::NativeHandle v) const {
|
||||
*m_ptr = v;
|
||||
}
|
||||
|
||||
ALWAYS_INLINE const os::NativeHandle &GetValue() const {
|
||||
ALWAYS_INLINE const tipc::NativeHandle &GetValue() const {
|
||||
return *m_ptr;
|
||||
}
|
||||
|
||||
ALWAYS_INLINE os::NativeHandle *GetPointer() const {
|
||||
ALWAYS_INLINE tipc::NativeHandle *GetPointer() const {
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
/* Convenience operators. */
|
||||
ALWAYS_INLINE os::NativeHandle &operator*() const {
|
||||
ALWAYS_INLINE tipc::NativeHandle &operator*() const {
|
||||
return *m_ptr;
|
||||
}
|
||||
|
||||
ALWAYS_INLINE os::NativeHandle *operator->() const {
|
||||
ALWAYS_INLINE tipc::NativeHandle *operator->() const {
|
||||
return m_ptr;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright (c) 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/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <vapours.hpp>
|
||||
|
||||
namespace ams::tipc {
|
||||
|
||||
namespace impl {
|
||||
|
||||
template<typename HandleType>
|
||||
class DummyMessageBuffer {
|
||||
public:
|
||||
class MessageHeader {
|
||||
public:
|
||||
MessageHeader() { AMS_ABORT("TODO"); }
|
||||
MessageHeader(const DummyMessageBuffer &) { AMS_ABORT("TODO"); }
|
||||
|
||||
u16 GetTag() const { AMS_ABORT("TODO"); }
|
||||
};
|
||||
class SpecialHeader {
|
||||
public:
|
||||
SpecialHeader() { AMS_ABORT("TODO"); }
|
||||
SpecialHeader(const DummyMessageBuffer &, const MessageHeader &) { AMS_ABORT("TODO"); }
|
||||
|
||||
bool GetHasProcessId() const { AMS_ABORT("TODO"); }
|
||||
s32 GetCopyHandleCount() const { AMS_ABORT("TODO"); }
|
||||
};
|
||||
public:
|
||||
DummyMessageBuffer(u32 *) { AMS_ABORT("TODO"); }
|
||||
DummyMessageBuffer(u32 *, size_t) { AMS_ABORT("TODO"); }
|
||||
|
||||
void SetNull() const { AMS_ABORT("TODO"); }
|
||||
|
||||
HandleType GetHandle(s32) const { AMS_ABORT("TODO"); }
|
||||
|
||||
template<typename T>
|
||||
const T &GetRaw(s32) const { AMS_ABORT("TODO"); }
|
||||
|
||||
static s32 GetSpecialDataIndex(const MessageHeader &, const SpecialHeader &) { AMS_ABORT("TODO"); }
|
||||
static s32 GetRawDataIndex(const MessageHeader &, const SpecialHeader &) { AMS_ABORT("TODO"); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#if defined(ATMOSPHERE_OS_HORIZON)
|
||||
|
||||
constexpr inline auto MaximumSessionsPerPort = svc::ArgumentHandleCountMax;
|
||||
|
||||
using NativeHandle = svc::Handle;
|
||||
constexpr inline NativeHandle InvalidNativeHandle = svc::InvalidHandle;
|
||||
|
||||
using MessageBuffer = ::ams::svc::ipc::MessageBuffer;
|
||||
|
||||
ALWAYS_INLINE u32 *GetMessageBuffer() { return svc::ipc::GetMessageBuffer(); }
|
||||
|
||||
constexpr ALWAYS_INLINE u32 EncodeNativeHandleForMessageQueue(NativeHandle h) { return static_cast<u32>(h); }
|
||||
constexpr ALWAYS_INLINE NativeHandle DecodeNativeHandleForMessageQueue(u32 v) { return static_cast<NativeHandle>(v); }
|
||||
|
||||
#elif defined(ATMOSPHERE_OS_WINDOWS)
|
||||
|
||||
/* TODO */
|
||||
constexpr inline auto MaximumSessionsPerPort = 0x40;
|
||||
|
||||
using NativeHandle = void *;
|
||||
constexpr inline NativeHandle InvalidNativeHandle = nullptr;
|
||||
|
||||
using MessageBuffer = ::ams::tipc::impl::DummyMessageBuffer<NativeHandle>;
|
||||
|
||||
ALWAYS_INLINE u32 *GetMessageBuffer() { AMS_ABORT("TODO"); }
|
||||
|
||||
ALWAYS_INLINE u32 EncodeNativeHandleForMessageQueue(NativeHandle) { AMS_ABORT("TODO"); }
|
||||
ALWAYS_INLINE NativeHandle DecodeNativeHandleForMessageQueue(u32) { AMS_ABORT("TODO"); }
|
||||
|
||||
#elif defined(ATMOSPHERE_OS_LINUX)
|
||||
|
||||
/* TODO */
|
||||
constexpr inline auto MaximumSessionsPerPort = 0x40;
|
||||
|
||||
using NativeHandle = s32;
|
||||
constexpr inline NativeHandle InvalidNativeHandle = -1;
|
||||
|
||||
using MessageBuffer = ::ams::tipc::impl::DummyMessageBuffer<NativeHandle>;
|
||||
|
||||
ALWAYS_INLINE u32 *GetMessageBuffer() { AMS_ABORT("TODO"); }
|
||||
|
||||
ALWAYS_INLINE u32 EncodeNativeHandleForMessageQueue(NativeHandle) { AMS_ABORT("TODO"); }
|
||||
ALWAYS_INLINE NativeHandle DecodeNativeHandleForMessageQueue(u32) { AMS_ABORT("TODO"); }
|
||||
|
||||
#elif defined(ATMOSPHERE_OS_MACOS)
|
||||
|
||||
/* TODO */
|
||||
constexpr inline auto MaximumSessionsPerPort = 0x40;
|
||||
|
||||
using NativeHandle = s32;
|
||||
constexpr inline NativeHandle InvalidNativeHandle = -1;
|
||||
|
||||
using MessageBuffer = ::ams::tipc::impl::DummyMessageBuffer<NativeHandle>;
|
||||
|
||||
ALWAYS_INLINE u32 *GetMessageBuffer() { AMS_ABORT("TODO"); }
|
||||
|
||||
ALWAYS_INLINE u32 EncodeNativeHandleForMessageQueue(NativeHandle) { AMS_ABORT("TODO"); }
|
||||
ALWAYS_INLINE NativeHandle DecodeNativeHandleForMessageQueue(u32) { AMS_ABORT("TODO"); }
|
||||
|
||||
#else
|
||||
#error "Unknown OS for tipc platform types."
|
||||
#endif
|
||||
|
||||
namespace impl {
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -30,12 +30,12 @@ namespace ams::tipc {
|
||||
ObjectType_Deferral = ObjectType_Invalid,
|
||||
};
|
||||
private:
|
||||
os::NativeHandle m_handle;
|
||||
tipc::NativeHandle m_handle;
|
||||
ObjectType m_type;
|
||||
bool m_managed;
|
||||
tipc::ServiceObjectBase *m_object;
|
||||
private:
|
||||
void InitializeImpl(ObjectType type, os::NativeHandle handle, bool managed, tipc::ServiceObjectBase *object) {
|
||||
void InitializeImpl(ObjectType type, tipc::NativeHandle handle, bool managed, tipc::ServiceObjectBase *object) {
|
||||
/* Validate that the object isn't already constructed. */
|
||||
AMS_ASSERT(m_type == ObjectType_Invalid);
|
||||
|
||||
@@ -46,20 +46,20 @@ namespace ams::tipc {
|
||||
m_object = object;
|
||||
}
|
||||
public:
|
||||
constexpr inline ObjectHolder() : m_handle(os::InvalidNativeHandle), m_type(ObjectType_Invalid), m_managed(false), m_object(nullptr) { /* ... */ }
|
||||
constexpr inline ObjectHolder() : m_handle(tipc::InvalidNativeHandle), m_type(ObjectType_Invalid), m_managed(false), m_object(nullptr) { /* ... */ }
|
||||
|
||||
void InitializeAsPort(os::NativeHandle handle) {
|
||||
void InitializeAsPort(tipc::NativeHandle handle) {
|
||||
/* NOTE: Nintendo sets ports as managed, but this will cause a nullptr-deref if one is ever closed. */
|
||||
/* This is theoretically a non-issue, as ports can't be closed, but we will set ours as unmanaged, */
|
||||
/* just in case. */
|
||||
this->InitializeImpl(ObjectType_Port, handle, false, nullptr);
|
||||
}
|
||||
|
||||
void InitializeAsSession(os::NativeHandle handle, bool managed, tipc::ServiceObjectBase *object) {
|
||||
void InitializeAsSession(tipc::NativeHandle handle, bool managed, tipc::ServiceObjectBase *object) {
|
||||
this->InitializeImpl(ObjectType_Session, handle, managed, object);
|
||||
}
|
||||
|
||||
void InitializeForDeferralManager(os::NativeHandle handle, tipc::ServiceObjectBase *object) {
|
||||
void InitializeForDeferralManager(tipc::NativeHandle handle, tipc::ServiceObjectBase *object) {
|
||||
this->InitializeImpl(ObjectType_Deferral, handle, false, object);
|
||||
}
|
||||
|
||||
@@ -75,13 +75,13 @@ namespace ams::tipc {
|
||||
}
|
||||
|
||||
/* Reset all fields. */
|
||||
m_handle = os::InvalidNativeHandle;
|
||||
m_handle = tipc::InvalidNativeHandle;
|
||||
m_type = ObjectType_Invalid;
|
||||
m_managed = false;
|
||||
m_object = nullptr;
|
||||
}
|
||||
|
||||
constexpr os::NativeHandle GetHandle() const {
|
||||
constexpr tipc::NativeHandle GetHandle() const {
|
||||
return m_handle;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#pragma once
|
||||
#include <vapours.hpp>
|
||||
#include <stratosphere/tipc/tipc_common.hpp>
|
||||
#include <stratosphere/tipc/impl/tipc_impl_message_api.hpp>
|
||||
#include <stratosphere/tipc/tipc_service_object.hpp>
|
||||
#include <stratosphere/tipc/tipc_object_holder.hpp>
|
||||
|
||||
@@ -37,7 +38,7 @@ namespace ams::tipc {
|
||||
Entry *m_entries_end{};
|
||||
os::MultiWaitType *m_multi_wait{};
|
||||
private:
|
||||
Entry *FindEntry(os::NativeHandle handle) {
|
||||
Entry *FindEntry(tipc::NativeHandle handle) {
|
||||
for (Entry *cur = m_entries_start; cur != m_entries_end; ++cur) {
|
||||
if (GetReference(cur->object).GetHandle() == handle) {
|
||||
return cur;
|
||||
@@ -76,7 +77,7 @@ namespace ams::tipc {
|
||||
std::scoped_lock lk(m_mutex);
|
||||
|
||||
/* Find an empty entry. */
|
||||
auto *entry = this->FindEntry(os::InvalidNativeHandle);
|
||||
auto *entry = this->FindEntry(tipc::InvalidNativeHandle);
|
||||
AMS_ABORT_UNLESS(entry != nullptr);
|
||||
|
||||
/* Set the entry's object. */
|
||||
@@ -87,7 +88,7 @@ namespace ams::tipc {
|
||||
os::LinkMultiWaitHolder(m_multi_wait, std::addressof(entry->multi_wait_holder));
|
||||
}
|
||||
|
||||
void CloseObject(os::NativeHandle handle) {
|
||||
void CloseObject(tipc::NativeHandle handle) {
|
||||
/* Lock ourselves. */
|
||||
std::scoped_lock lk(m_mutex);
|
||||
|
||||
@@ -103,14 +104,14 @@ namespace ams::tipc {
|
||||
GetReference(entry->object).Destroy();
|
||||
}
|
||||
|
||||
Result ReplyAndReceive(os::MultiWaitHolderType **out_holder, ObjectHolder *out_object, os::NativeHandle reply_target, os::MultiWaitType *multi_wait) {
|
||||
Result ReplyAndReceive(os::MultiWaitHolderType **out_holder, ObjectHolder *out_object, tipc::NativeHandle reply_target, os::MultiWaitType *multi_wait) {
|
||||
/* Declare signaled holder for processing ahead of time. */
|
||||
os::MultiWaitHolderType *signaled_holder;
|
||||
|
||||
/* Reply and receive until we get a newly signaled target. */
|
||||
Result result = os::SdkReplyAndReceive(out_holder, reply_target, multi_wait);
|
||||
for (signaled_holder = *out_holder; signaled_holder == nullptr; signaled_holder = *out_holder) {
|
||||
result = os::SdkReplyAndReceive(out_holder, os::InvalidNativeHandle, multi_wait);
|
||||
result = os::SdkReplyAndReceive(out_holder, tipc::InvalidNativeHandle, multi_wait);
|
||||
}
|
||||
|
||||
/* Find the entry matching the signaled holder. */
|
||||
@@ -125,32 +126,23 @@ namespace ams::tipc {
|
||||
}
|
||||
}
|
||||
|
||||
void Reply(os::NativeHandle reply_target) {
|
||||
/* Perform the reply. */
|
||||
s32 dummy;
|
||||
R_TRY_CATCH(svc::ReplyAndReceive(std::addressof(dummy), nullptr, 0, reply_target, 0)) {
|
||||
R_CATCH(svc::ResultTimedOut) {
|
||||
/* Timing out is acceptable. */
|
||||
}
|
||||
R_CATCH(svc::ResultSessionClosed) {
|
||||
/* It's okay if we couldn't reply to a closed session. */
|
||||
}
|
||||
} R_END_TRY_CATCH_WITH_ABORT_UNLESS;
|
||||
void Reply(tipc::NativeHandle reply_target) {
|
||||
return tipc::impl::Reply(reply_target);
|
||||
}
|
||||
|
||||
Result ProcessRequest(ObjectHolder &object) {
|
||||
/* Get the message buffer. */
|
||||
const svc::ipc::MessageBuffer message_buffer(svc::ipc::GetMessageBuffer());
|
||||
const MessageBuffer message_buffer(tipc::GetMessageBuffer());
|
||||
|
||||
/* Get the method id. */
|
||||
const auto method_id = svc::ipc::MessageBuffer::MessageHeader(message_buffer).GetTag();
|
||||
const auto method_id = MessageBuffer::MessageHeader(message_buffer).GetTag();
|
||||
|
||||
/* Process for the method id. */
|
||||
{
|
||||
/* Ensure that if we fail, we clean up any handles that get sent our way. */
|
||||
ON_RESULT_FAILURE {
|
||||
const svc::ipc::MessageBuffer::MessageHeader message_header(message_buffer);
|
||||
const svc::ipc::MessageBuffer::SpecialHeader special_header(message_buffer, message_header);
|
||||
const MessageBuffer::MessageHeader message_header(message_buffer);
|
||||
const MessageBuffer::SpecialHeader special_header(message_buffer, message_header);
|
||||
|
||||
/* Determine the offset to the start of handles. */
|
||||
auto offset = message_buffer.GetSpecialDataIndex(message_header, special_header);
|
||||
@@ -160,8 +152,8 @@ namespace ams::tipc {
|
||||
|
||||
/* Close all copy handles. */
|
||||
for (auto i = 0; i < special_header.GetCopyHandleCount(); ++i) {
|
||||
svc::CloseHandle(message_buffer.GetHandle(offset));
|
||||
offset += sizeof(ams::svc::Handle) / sizeof(u32);
|
||||
tipc::impl::CloseHandle(message_buffer.GetHandle(offset));
|
||||
offset += sizeof(typename std::remove_reference<decltype(message_buffer.GetHandle(offset))>::type) / sizeof(u32);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -191,7 +183,7 @@ namespace ams::tipc {
|
||||
|
||||
/* Close the object's handle. */
|
||||
/* NOTE: Nintendo does not check that this succeeds. */
|
||||
R_ABORT_UNLESS(svc::CloseHandle(handle));
|
||||
R_ABORT_UNLESS(tipc::impl::CloseHandle(handle));
|
||||
|
||||
/* Return an error to signify we closed the object. */
|
||||
R_THROW(tipc::ResultSessionClosed());
|
||||
|
||||
@@ -25,9 +25,9 @@ namespace ams::tipc {
|
||||
public:
|
||||
constexpr PointerAndSize() : m_pointer(0), m_size(0) { /* ... */ }
|
||||
constexpr PointerAndSize(uintptr_t ptr, size_t sz) : m_pointer(ptr), m_size(sz) { /* ... */ }
|
||||
constexpr PointerAndSize(void *ptr, size_t sz) : PointerAndSize(reinterpret_cast<uintptr_t>(ptr), sz) { /* ... */ }
|
||||
PointerAndSize(void *ptr, size_t sz) : PointerAndSize(reinterpret_cast<uintptr_t>(ptr), sz) { /* ... */ }
|
||||
|
||||
constexpr ALWAYS_INLINE void *GetPointer() const {
|
||||
ALWAYS_INLINE void *GetPointer() const {
|
||||
return reinterpret_cast<void *>(m_pointer);
|
||||
}
|
||||
|
||||
|
||||
@@ -50,16 +50,16 @@ namespace ams::tipc {
|
||||
static_assert(NumPorts > 0);
|
||||
|
||||
/* Verify that it's possible to service this many sessions, with our port manager count. */
|
||||
static_assert(MaxSessions <= NumPorts * svc::ArgumentHandleCountMax);
|
||||
static_assert(MaxSessions <= NumPorts * MaximumSessionsPerPort);
|
||||
|
||||
static_assert(util::IsAligned(ThreadStackSize, os::ThreadStackAlignment));
|
||||
alignas(os::ThreadStackAlignment) static constinit inline u8 s_port_stacks[ThreadStackSize * (NumPorts - 1)];
|
||||
|
||||
template<size_t Ix> requires (Ix < NumPorts)
|
||||
template<size_t Ix> AMS_CONCEPTS_REQUIRES_IF_SUPPORTED(Ix < NumPorts)
|
||||
static constexpr inline size_t SessionsPerPortManager = (Ix == NumPorts - 1) ? ((MaxSessions / NumPorts) + MaxSessions % NumPorts)
|
||||
: ((MaxSessions / NumPorts));
|
||||
|
||||
template<size_t Ix> requires (Ix < NumPorts)
|
||||
template<size_t Ix> AMS_CONCEPTS_REQUIRES_IF_SUPPORTED(Ix < NumPorts)
|
||||
using PortInfo = typename std::tuple_element<Ix, std::tuple<PortInfos...>>::type;
|
||||
|
||||
static_assert(IsDeferralSupported == (PortInfos::CanDeferInvokeRequest || ...));
|
||||
@@ -69,7 +69,7 @@ namespace ams::tipc {
|
||||
|
||||
using DeferralManagerBaseType = typename std::conditional<IsDeferralSupported, DeferralManagerBase, DummyDeferralManagerBase>::type;
|
||||
|
||||
template<size_t Ix> requires (Ix < NumPorts)
|
||||
template<size_t Ix> AMS_CONCEPTS_REQUIRES_IF_SUPPORTED(Ix < NumPorts)
|
||||
static constexpr inline bool IsPortDeferrable = PortInfo<Ix>::CanDeferInvokeRequest;
|
||||
public:
|
||||
class PortManagerBase {
|
||||
@@ -125,7 +125,7 @@ namespace ams::tipc {
|
||||
m_deferral_manager = dm;
|
||||
}
|
||||
|
||||
void RegisterPort(s32 index, os::NativeHandle port_handle) {
|
||||
void RegisterPort(s32 index, tipc::NativeHandle port_handle) {
|
||||
/* Set our port number. */
|
||||
m_port_number = index;
|
||||
|
||||
@@ -139,7 +139,7 @@ namespace ams::tipc {
|
||||
m_object_manager->AddObject(object);
|
||||
}
|
||||
|
||||
os::NativeHandle ProcessRequest(ObjectHolder &object) {
|
||||
tipc::NativeHandle ProcessRequest(ObjectHolder &object) {
|
||||
/* Acquire exclusive server manager access. */
|
||||
std::scoped_lock lk(m_server_manager->GetMutex());
|
||||
|
||||
@@ -147,13 +147,13 @@ namespace ams::tipc {
|
||||
const Result result = m_object_manager->ProcessRequest(object);
|
||||
if (R_SUCCEEDED(result)) {
|
||||
/* We should reply only if the request isn't deferred. */
|
||||
return !IsRequestDeferred() ? object.GetHandle() : os::InvalidNativeHandle;
|
||||
return !IsRequestDeferred() ? object.GetHandle() : tipc::InvalidNativeHandle;
|
||||
} else {
|
||||
/* Processing failed, so note the session as closed (or close it). */
|
||||
this->CloseSessionIfNecessary(object, !tipc::ResultSessionClosed::Includes(result));
|
||||
|
||||
/* We shouldn't reply on failure. */
|
||||
return os::InvalidNativeHandle;
|
||||
return tipc::InvalidNativeHandle;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,15 +161,15 @@ namespace ams::tipc {
|
||||
void ProcessDeferredRequest(ObjectHolder &object) {
|
||||
static_assert(Enable == IsDeferralSupported);
|
||||
|
||||
if (const auto reply_target = this->ProcessRequest(object); reply_target != os::InvalidNativeHandle) {
|
||||
if (const auto reply_target = this->ProcessRequest(object); reply_target != tipc::InvalidNativeHandle) {
|
||||
m_object_manager->Reply(reply_target);
|
||||
}
|
||||
}
|
||||
|
||||
bool ReplyAndReceive(os::MultiWaitHolderType **out_holder, ObjectHolder *out_object, os::NativeHandle reply_target) {
|
||||
bool ReplyAndReceive(os::MultiWaitHolderType **out_holder, ObjectHolder *out_object, tipc::NativeHandle reply_target) {
|
||||
/* If we don't have a reply target, clear our message buffer. */
|
||||
if (reply_target == os::InvalidNativeHandle) {
|
||||
svc::ipc::MessageBuffer(svc::ipc::GetMessageBuffer()).SetNull();
|
||||
if (reply_target == tipc::InvalidNativeHandle) {
|
||||
tipc::MessageBuffer(tipc::GetMessageBuffer()).SetNull();
|
||||
}
|
||||
|
||||
/* Try to reply/receive. */
|
||||
@@ -192,7 +192,7 @@ namespace ams::tipc {
|
||||
return true;
|
||||
}
|
||||
|
||||
void AddSession(os::NativeHandle session_handle, tipc::ServiceObjectBase *service_object) {
|
||||
void AddSession(tipc::NativeHandle session_handle, tipc::ServiceObjectBase *service_object) {
|
||||
/* Create an object holder for the session. */
|
||||
tipc::ObjectHolder object;
|
||||
|
||||
@@ -215,7 +215,7 @@ namespace ams::tipc {
|
||||
case MessageType_AddSession:
|
||||
{
|
||||
/* Get the handle from where it's packed into the message type. */
|
||||
const os::NativeHandle session_handle = static_cast<os::NativeHandle>(message_type >> BITSIZEOF(u32));
|
||||
const tipc::NativeHandle session_handle = tipc::DecodeNativeHandleForMessageQueue(message_type >> BITSIZEOF(u32));
|
||||
|
||||
/* Allocate a service object for the port. */
|
||||
auto *service_object = m_server_manager->AllocateObject(static_cast<size_t>(message_data), session_handle, *m_deferral_manager);
|
||||
@@ -243,7 +243,7 @@ namespace ams::tipc {
|
||||
m_object_manager->CloseObject(handle);
|
||||
|
||||
/* Close the handle itself. */
|
||||
R_ABORT_UNLESS(svc::CloseHandle(handle));
|
||||
R_ABORT_UNLESS(tipc::impl::CloseHandle(handle));
|
||||
|
||||
/* Decrement our session count. */
|
||||
--m_num_sessions;
|
||||
@@ -258,7 +258,7 @@ namespace ams::tipc {
|
||||
m_object_manager->CloseObject(handle);
|
||||
|
||||
/* Close the handle itself. */
|
||||
R_ABORT_UNLESS(svc::CloseHandle(handle));
|
||||
R_ABORT_UNLESS(tipc::impl::CloseHandle(handle));
|
||||
}
|
||||
|
||||
/* Decrement our session count. */
|
||||
@@ -286,12 +286,12 @@ namespace ams::tipc {
|
||||
os::SendMessageQueue(std::addressof(m_message_queue), key);
|
||||
}
|
||||
|
||||
void TriggerAddSession(os::NativeHandle session_handle, size_t port_index) {
|
||||
void TriggerAddSession(tipc::NativeHandle session_handle, size_t port_index) {
|
||||
/* Increment our session count. */
|
||||
++m_num_sessions;
|
||||
|
||||
/* Send information about the session as a message. */
|
||||
os::SendMessageQueue(std::addressof(m_message_queue), static_cast<uintptr_t>(MessageType_AddSession) | (static_cast<u64>(session_handle) << BITSIZEOF(u32)));
|
||||
os::SendMessageQueue(std::addressof(m_message_queue), static_cast<uintptr_t>(MessageType_AddSession) | (static_cast<u64>(tipc::EncodeNativeHandleForMessageQueue(session_handle)) << BITSIZEOF(u32)));
|
||||
os::SendMessageQueue(std::addressof(m_message_queue), static_cast<uintptr_t>(port_index));
|
||||
}
|
||||
private:
|
||||
@@ -306,11 +306,11 @@ namespace ams::tipc {
|
||||
static bool IsRequestDeferred() {
|
||||
if constexpr (IsDeferralSupported) {
|
||||
/* Get the message buffer. */
|
||||
const svc::ipc::MessageBuffer message_buffer(svc::ipc::GetMessageBuffer());
|
||||
const tipc::MessageBuffer message_buffer(tipc::GetMessageBuffer());
|
||||
|
||||
/* Parse the hipc headers. */
|
||||
const svc::ipc::MessageBuffer::MessageHeader message_header(message_buffer);
|
||||
const svc::ipc::MessageBuffer::SpecialHeader special_header(message_buffer, message_header);
|
||||
const tipc::MessageBuffer::MessageHeader message_header(message_buffer);
|
||||
const tipc::MessageBuffer::SpecialHeader special_header(message_buffer, message_header);
|
||||
|
||||
/* Determine raw data index. */
|
||||
const auto raw_data_offset = message_buffer.GetRawDataIndex(message_header, special_header);
|
||||
@@ -406,14 +406,14 @@ namespace ams::tipc {
|
||||
}
|
||||
|
||||
template<size_t Ix>
|
||||
void RegisterPort(os::NativeHandle port_handle) {
|
||||
void RegisterPort(tipc::NativeHandle port_handle) {
|
||||
this->GetPortManager<Ix>().RegisterPort(static_cast<s32>(Ix), port_handle);
|
||||
}
|
||||
|
||||
template<size_t Ix>
|
||||
void RegisterPort(sm::ServiceName service_name, size_t max_sessions) {
|
||||
/* Register service. */
|
||||
os::NativeHandle port_handle;
|
||||
tipc::NativeHandle port_handle;
|
||||
R_ABORT_UNLESS(sm::RegisterService(std::addressof(port_handle), service_name, max_sessions, false));
|
||||
|
||||
/* Register the port handle. */
|
||||
@@ -454,7 +454,7 @@ namespace ams::tipc {
|
||||
this->LoopAutoForPort<NumPorts - 1>();
|
||||
}
|
||||
|
||||
tipc::ServiceObjectBase *AllocateObject(size_t port_index, os::NativeHandle handle, DeferralManagerBaseType &deferral_manager) {
|
||||
tipc::ServiceObjectBase *AllocateObject(size_t port_index, tipc::NativeHandle handle, DeferralManagerBaseType &deferral_manager) {
|
||||
/* Check that the port index is valid. */
|
||||
AMS_ABORT_UNLESS(port_index < NumPorts);
|
||||
|
||||
@@ -483,13 +483,13 @@ namespace ams::tipc {
|
||||
}(std::make_index_sequence<NumPorts>());
|
||||
}
|
||||
|
||||
Result AddSession(os::NativeHandle *out, tipc::ServiceObjectBase *object) {
|
||||
Result AddSession(tipc::NativeHandle *out, tipc::ServiceObjectBase *object) {
|
||||
/* Acquire exclusive access to ourselves. */
|
||||
std::scoped_lock lk(m_mutex);
|
||||
|
||||
/* Create a handle for the session. */
|
||||
svc::Handle session_handle;
|
||||
R_TRY(svc::CreateSession(std::addressof(session_handle), static_cast<svc::Handle *>(out), false, 0));
|
||||
tipc::NativeHandle session_handle;
|
||||
R_TRY(tipc::impl::CreateSession(std::addressof(session_handle), static_cast<tipc::NativeHandle *>(out), false, 0));
|
||||
|
||||
/* Select the best port manager. */
|
||||
PortManagerBase *best_manager = nullptr;
|
||||
@@ -505,7 +505,7 @@ namespace ams::tipc {
|
||||
}
|
||||
private:
|
||||
template<size_t Ix> requires (Ix < NumPorts)
|
||||
void TryAllocateObject(size_t port_index, os::NativeHandle handle, DeferralManagerBaseType &deferral_manager, tipc::ServiceObjectBase *&allocated) {
|
||||
void TryAllocateObject(size_t port_index, tipc::NativeHandle handle, DeferralManagerBaseType &deferral_manager, tipc::ServiceObjectBase *&allocated) {
|
||||
/* Check that the port index matches. */
|
||||
if (port_index == Ix) {
|
||||
/* Check that we haven't already allocated. */
|
||||
@@ -535,13 +535,13 @@ namespace ams::tipc {
|
||||
|
||||
Result LoopProcess(PortManagerBase &port_manager) {
|
||||
/* Process requests forever. */
|
||||
os::NativeHandle reply_target = os::InvalidNativeHandle;
|
||||
tipc::NativeHandle reply_target = tipc::InvalidNativeHandle;
|
||||
while (true) {
|
||||
/* Reply to our pending request, and wait to receive a new one. */
|
||||
os::MultiWaitHolderType *signaled_holder = nullptr;
|
||||
tipc::ObjectHolder signaled_object{};
|
||||
while (!port_manager.ReplyAndReceive(std::addressof(signaled_holder), std::addressof(signaled_object), reply_target)) {
|
||||
reply_target = os::InvalidNativeHandle;
|
||||
reply_target = tipc::InvalidNativeHandle;
|
||||
signaled_object = {};
|
||||
}
|
||||
|
||||
@@ -551,13 +551,13 @@ namespace ams::tipc {
|
||||
case ObjectHolder::ObjectType_Port:
|
||||
{
|
||||
/* Try to accept a new session */
|
||||
svc::Handle session_handle;
|
||||
if (R_SUCCEEDED(svc::AcceptSession(std::addressof(session_handle), signaled_object.GetHandle()))) {
|
||||
tipc::NativeHandle session_handle;
|
||||
if (R_SUCCEEDED(tipc::impl::AcceptSession(std::addressof(session_handle), signaled_object.GetHandle()))) {
|
||||
this->TriggerAddSession(session_handle, static_cast<size_t>(port_manager.GetPortIndex()));
|
||||
}
|
||||
|
||||
/* We have nothing to reply to. */
|
||||
reply_target = os::InvalidNativeHandle;
|
||||
reply_target = tipc::InvalidNativeHandle;
|
||||
}
|
||||
break;
|
||||
case ObjectHolder::ObjectType_Session:
|
||||
@@ -573,12 +573,12 @@ namespace ams::tipc {
|
||||
port_manager.ProcessMessages();
|
||||
|
||||
/* We have nothing to reply to. */
|
||||
reply_target = os::InvalidNativeHandle;
|
||||
reply_target = tipc::InvalidNativeHandle;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TriggerAddSession(os::NativeHandle session_handle, size_t port_index) {
|
||||
void TriggerAddSession(tipc::NativeHandle session_handle, size_t port_index) {
|
||||
/* Acquire exclusive access to ourselves. */
|
||||
std::scoped_lock lk(m_mutex);
|
||||
|
||||
@@ -634,7 +634,7 @@ namespace ams::tipc {
|
||||
static constexpr inline size_t MaxSessions = PortInfo::MaxSessions;
|
||||
|
||||
/* Verify that it's possible to service this many sessions, with our port manager count. */
|
||||
static_assert(MaxSessions <= svc::ArgumentHandleCountMax);
|
||||
static_assert(MaxSessions <= MaximumSessionsPerPort);
|
||||
public:
|
||||
class PortManagerBase {
|
||||
protected:
|
||||
@@ -651,7 +651,7 @@ namespace ams::tipc {
|
||||
m_object_manager = om;
|
||||
}
|
||||
|
||||
void RegisterPort(os::NativeHandle port_handle) {
|
||||
void RegisterPort(tipc::NativeHandle port_handle) {
|
||||
/* Create an object holder for the port. */
|
||||
tipc::ObjectHolder object;
|
||||
|
||||
@@ -662,7 +662,7 @@ namespace ams::tipc {
|
||||
m_object_manager->AddObject(object);
|
||||
}
|
||||
|
||||
os::NativeHandle ProcessRequest(ObjectHolder &object) {
|
||||
tipc::NativeHandle ProcessRequest(ObjectHolder &object) {
|
||||
/* Process the request. */
|
||||
const Result result = m_object_manager->ProcessRequest(object);
|
||||
if (R_SUCCEEDED(result)) {
|
||||
@@ -675,14 +675,14 @@ namespace ams::tipc {
|
||||
}
|
||||
|
||||
/* We shouldn't reply on failure. */
|
||||
return os::InvalidNativeHandle;
|
||||
return tipc::InvalidNativeHandle;
|
||||
}
|
||||
}
|
||||
|
||||
bool ReplyAndReceive(ObjectHolder *out_object, os::NativeHandle reply_target) {
|
||||
bool ReplyAndReceive(ObjectHolder *out_object, tipc::NativeHandle reply_target) {
|
||||
/* If we don't have a reply target, clear our message buffer. */
|
||||
if (reply_target == os::InvalidNativeHandle) {
|
||||
svc::ipc::MessageBuffer(svc::ipc::GetMessageBuffer()).SetNull();
|
||||
if (reply_target == tipc::InvalidNativeHandle) {
|
||||
tipc::MessageBuffer(tipc::GetMessageBuffer()).SetNull();
|
||||
}
|
||||
|
||||
/* Try to reply/receive. */
|
||||
@@ -704,7 +704,7 @@ namespace ams::tipc {
|
||||
return true;
|
||||
}
|
||||
|
||||
void AddSession(os::NativeHandle session_handle, tipc::ServiceObjectBase *service_object) {
|
||||
void AddSession(tipc::NativeHandle session_handle, tipc::ServiceObjectBase *service_object) {
|
||||
/* Create an object holder for the session. */
|
||||
tipc::ObjectHolder object;
|
||||
|
||||
@@ -723,7 +723,7 @@ namespace ams::tipc {
|
||||
m_object_manager->CloseObject(handle);
|
||||
|
||||
/* Close the handle itself. */
|
||||
R_ABORT_UNLESS(svc::CloseHandle(handle));
|
||||
R_ABORT_UNLESS(tipc::impl::CloseHandle(handle));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -756,13 +756,13 @@ namespace ams::tipc {
|
||||
m_port_manager.Initialize();
|
||||
}
|
||||
|
||||
void RegisterPort(os::NativeHandle port_handle) {
|
||||
void RegisterPort(tipc::NativeHandle port_handle) {
|
||||
m_port_manager.RegisterPort(port_handle);
|
||||
}
|
||||
|
||||
void RegisterPort(sm::ServiceName service_name, size_t max_sessions) {
|
||||
/* Register service. */
|
||||
os::NativeHandle port_handle;
|
||||
tipc::NativeHandle port_handle;
|
||||
R_ABORT_UNLESS(sm::RegisterService(std::addressof(port_handle), service_name, max_sessions, false));
|
||||
|
||||
/* Register the port handle. */
|
||||
@@ -787,10 +787,10 @@ namespace ams::tipc {
|
||||
return new_object;
|
||||
}
|
||||
|
||||
Result AddSession(os::NativeHandle *out, tipc::ServiceObjectBase *object) {
|
||||
Result AddSession(tipc::NativeHandle *out, tipc::ServiceObjectBase *object) {
|
||||
/* Create a handle for the session. */
|
||||
svc::Handle session_handle;
|
||||
R_TRY(svc::CreateSession(std::addressof(session_handle), static_cast<svc::Handle *>(out), false, 0));
|
||||
tipc::NativeHandle session_handle;
|
||||
R_TRY(tipc::impl::CreateSession(std::addressof(session_handle), static_cast<tipc::NativeHandle *>(out), false, 0));
|
||||
|
||||
/* Add the session to our manager. */
|
||||
m_port_manager.AddSession(session_handle, object);
|
||||
@@ -800,12 +800,12 @@ namespace ams::tipc {
|
||||
private:
|
||||
void LoopProcess(PortManagerBase &port_manager) {
|
||||
/* Process requests forever. */
|
||||
os::NativeHandle reply_target = os::InvalidNativeHandle;
|
||||
tipc::NativeHandle reply_target = tipc::InvalidNativeHandle;
|
||||
while (true) {
|
||||
/* Reply to our pending request, and wait to receive a new one. */
|
||||
tipc::ObjectHolder signaled_object{};
|
||||
while (!port_manager.ReplyAndReceive(std::addressof(signaled_object), reply_target)) {
|
||||
reply_target = os::InvalidNativeHandle;
|
||||
reply_target = tipc::InvalidNativeHandle;
|
||||
}
|
||||
|
||||
/* A session was signaled, accessible via signaled_object. */
|
||||
@@ -813,13 +813,13 @@ namespace ams::tipc {
|
||||
case ObjectHolder::ObjectType_Port:
|
||||
{
|
||||
/* Try to accept a new session */
|
||||
svc::Handle session_handle;
|
||||
if (R_SUCCEEDED(svc::AcceptSession(std::addressof(session_handle), signaled_object.GetHandle()))) {
|
||||
tipc::NativeHandle session_handle;
|
||||
if (R_SUCCEEDED(tipc::impl::AcceptSession(std::addressof(session_handle), signaled_object.GetHandle()))) {
|
||||
port_manager.AddSession(session_handle, this->AllocateObject());
|
||||
}
|
||||
|
||||
/* We have nothing to reply to. */
|
||||
reply_target = os::InvalidNativeHandle;
|
||||
reply_target = tipc::InvalidNativeHandle;
|
||||
}
|
||||
break;
|
||||
case ObjectHolder::ObjectType_Session:
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace ams::tipc {
|
||||
|
||||
template<typename Impl>
|
||||
class EmplacedImplHolder {
|
||||
template<typename, typename, typename, typename>
|
||||
template<typename, typename, typename, typename, typename>
|
||||
friend class impl::ImplTemplateBaseT;
|
||||
private:
|
||||
using Impl2 = typename EmplacedImplHolderBaseGetter<Impl>::Type;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
#pragma once
|
||||
#include <vapours.hpp>
|
||||
#include <stratosphere/tipc/tipc_message_types.hpp>
|
||||
|
||||
namespace ams::tipc {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user