1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 #if defined(OS_WIN) 11 #include "base/win/windows_types.h" 12 #endif 13 14 #include <memory> 15 #include <string> 16 17 #include "build/build_config.h" 18 #include "ipc/ipc_message.h" 19 #include "ipc/ipc_message_support_export.h" 20 21 namespace base { 22 class WaitableEvent; 23 } 24 25 namespace IPC { 26 27 class MessageReplyDeserializer; 28 29 class IPC_MESSAGE_SUPPORT_EXPORT SyncMessage : public Message { 30 public: 31 SyncMessage(int32_t routing_id, 32 uint32_t type, 33 PriorityValue priority, 34 MessageReplyDeserializer* deserializer); 35 ~SyncMessage() override; 36 37 // Call this to get a deserializer for the output parameters. 38 // Note that this can only be called once, and the caller is responsible 39 // for deleting the deserializer when they're done. 40 MessageReplyDeserializer* GetReplyDeserializer(); 41 42 // If this message can cause the receiver to block while waiting for user 43 // input (i.e. by calling MessageBox), then the caller needs to pump window 44 // messages and dispatch asynchronous messages while waiting for the reply. 45 // This call enables message pumping behavior while waiting for a reply to 46 // this message. EnableMessagePumping()47 void EnableMessagePumping() { 48 header()->flags |= PUMPING_MSGS_BIT; 49 } 50 51 // Indicates whether window messages should be pumped while waiting for a 52 // reply to this message. ShouldPumpMessages()53 bool ShouldPumpMessages() const { 54 return (header()->flags & PUMPING_MSGS_BIT) != 0; 55 } 56 57 // Returns true if the message is a reply to the given request id. 58 static bool IsMessageReplyTo(const Message& msg, int request_id); 59 60 // Given a reply message, returns an iterator to the beginning of the data 61 // (i.e. skips over the synchronous specific data). 62 static base::PickleIterator GetDataIterator(const Message* msg); 63 64 // Given a synchronous message (or its reply), returns its id. 65 static int GetMessageId(const Message& msg); 66 67 // Generates a reply message to the given message. 68 static Message* GenerateReply(const Message* msg); 69 70 private: 71 struct SyncHeader { 72 // unique ID (unique per sender) 73 int message_id; 74 }; 75 76 static bool ReadSyncHeader(const Message& msg, SyncHeader* header); 77 static bool WriteSyncHeader(Message* msg, const SyncHeader& header); 78 79 std::unique_ptr<MessageReplyDeserializer> deserializer_; 80 }; 81 82 // Used to deserialize parameters from a reply to a synchronous message 83 class IPC_MESSAGE_SUPPORT_EXPORT MessageReplyDeserializer { 84 public: ~MessageReplyDeserializer()85 virtual ~MessageReplyDeserializer() {} 86 bool SerializeOutputParameters(const Message& msg); 87 private: 88 // Derived classes need to implement this, using the given iterator (which 89 // is skipped past the header for synchronous messages). 90 virtual bool SerializeOutputParameters(const Message& msg, 91 base::PickleIterator iter) = 0; 92 }; 93 94 // When sending a synchronous message, this structure contains an object 95 // that knows how to deserialize the response. 96 struct PendingSyncMsg { PendingSyncMsgPendingSyncMsg97 PendingSyncMsg(int id, MessageReplyDeserializer* d, base::WaitableEvent* e) 98 : id(id), deserializer(d), done_event(e), send_result(false) {} 99 100 int id; 101 MessageReplyDeserializer* deserializer; 102 base::WaitableEvent* done_event; 103 bool send_result; 104 }; 105 106 } // namespace IPC 107 108 #endif // IPC_IPC_SYNC_MESSAGE_H_ 109