1 // Copyright 2012 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef IPC_IPC_SYNC_MESSAGE_H_ 6 #define IPC_IPC_SYNC_MESSAGE_H_ 7 8 #include <stdint.h> 9 10 #include <memory> 11 12 #include "build/build_config.h" 13 14 #if BUILDFLAG(IS_WIN) 15 #include "base/win/windows_types.h" 16 #endif 17 18 #include <memory> 19 #include <string> 20 21 #include "build/build_config.h" 22 #include "ipc/ipc_message.h" 23 #include "ipc/ipc_message_support_export.h" 24 25 namespace base { 26 class WaitableEvent; 27 } 28 29 namespace IPC { 30 31 class MessageReplyDeserializer; 32 33 class IPC_MESSAGE_SUPPORT_EXPORT SyncMessage : public Message { 34 public: 35 SyncMessage(int32_t routing_id, 36 uint32_t type, 37 PriorityValue priority, 38 std::unique_ptr<MessageReplyDeserializer> deserializer); 39 ~SyncMessage() override; 40 41 // Call this to get a deserializer for the output parameters. 42 // Note that this can only be called once, and the caller is takes 43 // ownership of the deserializer.. 44 std::unique_ptr<MessageReplyDeserializer> TakeReplyDeserializer(); 45 46 // Returns true if the message is a reply to the given request id. 47 static bool IsMessageReplyTo(const Message& msg, int request_id); 48 49 // Given a reply message, returns an iterator to the beginning of the data 50 // (i.e. skips over the synchronous specific data). 51 static base::PickleIterator GetDataIterator(const Message* msg); 52 53 // Given a synchronous message (or its reply), returns its id. 54 static int GetMessageId(const Message& msg); 55 56 // Generates a reply message to the given message. 57 static Message* GenerateReply(const Message* msg); 58 59 private: 60 struct SyncHeader { 61 // unique ID (unique per sender) 62 int message_id; 63 }; 64 65 static bool ReadSyncHeader(const Message& msg, SyncHeader* header); 66 static bool WriteSyncHeader(Message* msg, const SyncHeader& header); 67 68 std::unique_ptr<MessageReplyDeserializer> deserializer_; 69 }; 70 71 // Used to deserialize parameters from a reply to a synchronous message 72 class IPC_MESSAGE_SUPPORT_EXPORT MessageReplyDeserializer { 73 public: ~MessageReplyDeserializer()74 virtual ~MessageReplyDeserializer() {} 75 bool SerializeOutputParameters(const Message& msg); 76 private: 77 // Derived classes need to implement this, using the given iterator (which 78 // is skipped past the header for synchronous messages). 79 virtual bool SerializeOutputParameters(const Message& msg, 80 base::PickleIterator iter) = 0; 81 }; 82 83 // When sending a synchronous message, this structure contains an object 84 // that knows how to deserialize the response. 85 struct IPC_MESSAGE_SUPPORT_EXPORT PendingSyncMsg { 86 PendingSyncMsg(int id, 87 std::unique_ptr<MessageReplyDeserializer> d, 88 std::unique_ptr<base::WaitableEvent> e); 89 PendingSyncMsg(PendingSyncMsg&& that); 90 ~PendingSyncMsg(); 91 92 int id; 93 bool send_result = false; 94 std::unique_ptr<MessageReplyDeserializer> deserializer; 95 std::unique_ptr<base::WaitableEvent> done_event; 96 }; 97 98 } // namespace IPC 99 100 #endif // IPC_IPC_SYNC_MESSAGE_H_ 101