michael@0: // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. michael@0: // Use of this source code is governed by a BSD-style license that can be michael@0: // found in the LICENSE file. michael@0: michael@0: #ifndef CHROME_COMMON_IPC_SYNC_MESSAGE_H__ michael@0: #define CHROME_COMMON_IPC_SYNC_MESSAGE_H__ michael@0: michael@0: #if defined(OS_WIN) michael@0: #include michael@0: #endif michael@0: #include michael@0: #include "base/basictypes.h" michael@0: #include "chrome/common/ipc_message.h" michael@0: michael@0: namespace base { michael@0: class WaitableEvent; michael@0: } michael@0: michael@0: namespace IPC { michael@0: michael@0: class MessageReplyDeserializer; michael@0: michael@0: class SyncMessage : public Message { michael@0: public: michael@0: SyncMessage(int32_t routing_id, uint16_t type, PriorityValue priority, michael@0: MessageReplyDeserializer* deserializer); michael@0: michael@0: // Call this to get a deserializer for the output parameters. michael@0: // Note that this can only be called once, and the caller is responsible michael@0: // for deleting the deserializer when they're done. michael@0: MessageReplyDeserializer* GetReplyDeserializer(); michael@0: michael@0: // If this message can cause the receiver to block while waiting for user michael@0: // input (i.e. by calling MessageBox), then the caller needs to pump window michael@0: // messages and dispatch asynchronous messages while waiting for the reply. michael@0: // If this event is passed in, then window messages will start being pumped michael@0: // when it's set. Note that this behavior will continue even if the event is michael@0: // later reset. The event must be valid until after the Send call returns. michael@0: void set_pump_messages_event(base::WaitableEvent* event) { michael@0: pump_messages_event_ = event; michael@0: if (event) { michael@0: header()->flags |= PUMPING_MSGS_BIT; michael@0: } else { michael@0: header()->flags &= ~PUMPING_MSGS_BIT; michael@0: } michael@0: } michael@0: michael@0: // Call this if you always want to pump messages. You can call this method michael@0: // or set_pump_messages_event but not both. michael@0: void EnableMessagePumping(); michael@0: michael@0: base::WaitableEvent* pump_messages_event() const { michael@0: return pump_messages_event_; michael@0: } michael@0: michael@0: // Returns true if the message is a reply to the given request id. michael@0: static bool IsMessageReplyTo(const Message& msg, int request_id); michael@0: michael@0: // Given a reply message, returns an iterator to the beginning of the data michael@0: // (i.e. skips over the synchronous specific data). michael@0: static void* GetDataIterator(const Message* msg); michael@0: michael@0: // Given a synchronous message (or its reply), returns its id. michael@0: static int GetMessageId(const Message& msg); michael@0: michael@0: // Generates a reply message to the given message. michael@0: static Message* GenerateReply(const Message* msg); michael@0: michael@0: private: michael@0: struct SyncHeader { michael@0: // unique ID (unique per sender) michael@0: int message_id; michael@0: }; michael@0: michael@0: static bool ReadSyncHeader(const Message& msg, SyncHeader* header); michael@0: static bool WriteSyncHeader(Message* msg, const SyncHeader& header); michael@0: michael@0: MessageReplyDeserializer* deserializer_; michael@0: base::WaitableEvent* pump_messages_event_; michael@0: michael@0: static uint32_t next_id_; // for generation of unique ids michael@0: }; michael@0: michael@0: // Used to deserialize parameters from a reply to a synchronous message michael@0: class MessageReplyDeserializer { michael@0: public: michael@0: bool SerializeOutputParameters(const Message& msg); michael@0: virtual ~MessageReplyDeserializer() {} michael@0: private: michael@0: // Derived classes need to implement this, using the given iterator (which michael@0: // is skipped past the header for synchronous messages). michael@0: virtual bool SerializeOutputParameters(const Message& msg, void* iter) = 0; michael@0: }; michael@0: michael@0: } // namespace IPC michael@0: michael@0: #endif // CHROME_COMMON_IPC_SYNC_MESSAGE_H__