mirror of
				https://git.suyu.dev/suyu/suyu.git
				synced 2025-10-31 23:06:43 +08:00 
			
		
		
		
	kernel/hle_ipc: Convert std::shared_ptr IPC header instances to std::optional
There's no real need to use a shared lifetime here, since we don't actually expose them to anything else. This is also kind of an unnecessary use of the heap given the objects themselves are so small; small enough, in fact that changing over to optionals actually reduces the overall size of the HLERequestContext struct (818 bytes to 808 bytes).
This commit is contained in:
		
							parent
							
								
									69749a88cd
								
							
						
					
					
						commit
						fbb82e61e3
					
				| @ -350,7 +350,7 @@ public: | ||||
|     template <class T> | ||||
|     std::shared_ptr<T> PopIpcInterface() { | ||||
|         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); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| @ -86,7 +86,7 @@ HLERequestContext::~HLERequestContext() = default; | ||||
| void HLERequestContext::ParseCommandBuffer(const HandleTable& handle_table, u32_le* src_cmdbuf, | ||||
|                                            bool incoming) { | ||||
|     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) { | ||||
|         // 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 (command_header->enable_handle_descriptor) { | ||||
|         handle_descriptor_header = | ||||
|             std::make_shared<IPC::HandleDescriptorHeader>(rp.PopRaw<IPC::HandleDescriptorHeader>()); | ||||
|         handle_descriptor_header = rp.PopRaw<IPC::HandleDescriptorHeader>(); | ||||
|         if (handle_descriptor_header->send_current_pid) { | ||||
|             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
 | ||||
|         // All outgoing domain messages have the domain header, if only incoming has it
 | ||||
|         if (incoming || domain_message_header) { | ||||
|             domain_message_header = | ||||
|                 std::make_shared<IPC::DomainMessageHeader>(rp.PopRaw<IPC::DomainMessageHeader>()); | ||||
|             domain_message_header = rp.PopRaw<IPC::DomainMessageHeader>(); | ||||
|         } else { | ||||
|             if (Session()->IsDomain()) | ||||
|             if (Session()->IsDomain()) { | ||||
|                 LOG_WARNING(IPC, "Domain request has no DomainMessageHeader!"); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     data_payload_header = | ||||
|         std::make_shared<IPC::DataPayloadHeader>(rp.PopRaw<IPC::DataPayloadHeader>()); | ||||
|     data_payload_header = rp.PopRaw<IPC::DataPayloadHeader>(); | ||||
| 
 | ||||
|     data_payload_offset = rp.GetCurrentOffset(); | ||||
| 
 | ||||
|  | ||||
| @ -6,6 +6,7 @@ | ||||
| 
 | ||||
| #include <array> | ||||
| #include <memory> | ||||
| #include <optional> | ||||
| #include <string> | ||||
| #include <type_traits> | ||||
| #include <vector> | ||||
| @ -168,12 +169,12 @@ public: | ||||
|         return buffer_c_desciptors; | ||||
|     } | ||||
| 
 | ||||
|     const IPC::DomainMessageHeader* GetDomainMessageHeader() const { | ||||
|         return domain_message_header.get(); | ||||
|     const IPC::DomainMessageHeader& GetDomainMessageHeader() const { | ||||
|         return domain_message_header.value(); | ||||
|     } | ||||
| 
 | ||||
|     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
 | ||||
| @ -272,10 +273,10 @@ private: | ||||
|     boost::container::small_vector<SharedPtr<Object>, 8> copy_objects; | ||||
|     boost::container::small_vector<std::shared_ptr<SessionRequestHandler>, 8> domain_objects; | ||||
| 
 | ||||
|     std::shared_ptr<IPC::CommandHeader> command_header; | ||||
|     std::shared_ptr<IPC::HandleDescriptorHeader> handle_descriptor_header; | ||||
|     std::shared_ptr<IPC::DataPayloadHeader> data_payload_header; | ||||
|     std::shared_ptr<IPC::DomainMessageHeader> domain_message_header; | ||||
|     std::optional<IPC::CommandHeader> command_header; | ||||
|     std::optional<IPC::HandleDescriptorHeader> handle_descriptor_header; | ||||
|     std::optional<IPC::DataPayloadHeader> data_payload_header; | ||||
|     std::optional<IPC::DomainMessageHeader> domain_message_header; | ||||
|     std::vector<IPC::BufferDescriptorX> buffer_x_desciptors; | ||||
|     std::vector<IPC::BufferDescriptorABW> buffer_a_desciptors; | ||||
|     std::vector<IPC::BufferDescriptorABW> buffer_b_desciptors; | ||||
|  | ||||
| @ -92,41 +92,42 @@ std::size_t ServerSession::NumDomainRequestHandlers() const { | ||||
| } | ||||
| 
 | ||||
| ResultCode ServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& context) { | ||||
|     auto* const domain_message_header = context.GetDomainMessageHeader(); | ||||
|     if (domain_message_header) { | ||||
|         // 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); | ||||
|     if (!context.HasDomainMessageHeader()) { | ||||
|         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 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; | ||||
| } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user