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