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