1 : // Copyright (c) 2006-2008 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 CHROME_COMMON_IPC_SYNC_MESSAGE_H__
6 : #define CHROME_COMMON_IPC_SYNC_MESSAGE_H__
7 :
8 : #if defined(OS_WIN)
9 : #include <windows.h>
10 : #endif
11 : #include <string>
12 : #include "base/basictypes.h"
13 : #include "chrome/common/ipc_message.h"
14 :
15 : namespace base {
16 : class WaitableEvent;
17 : }
18 :
19 : namespace IPC {
20 :
21 : class MessageReplyDeserializer;
22 :
23 0 : class SyncMessage : public Message {
24 : public:
25 : SyncMessage(int32 routing_id, uint16 type, PriorityValue priority,
26 : MessageReplyDeserializer* deserializer);
27 :
28 : // Call this to get a deserializer for the output parameters.
29 : // Note that this can only be called once, and the caller is responsible
30 : // for deleting the deserializer when they're done.
31 : MessageReplyDeserializer* GetReplyDeserializer();
32 :
33 : // If this message can cause the receiver to block while waiting for user
34 : // input (i.e. by calling MessageBox), then the caller needs to pump window
35 : // messages and dispatch asynchronous messages while waiting for the reply.
36 : // If this event is passed in, then window messages will start being pumped
37 : // when it's set. Note that this behavior will continue even if the event is
38 : // later reset. The event must be valid until after the Send call returns.
39 0 : void set_pump_messages_event(base::WaitableEvent* event) {
40 0 : pump_messages_event_ = event;
41 0 : if (event) {
42 0 : header()->flags |= PUMPING_MSGS_BIT;
43 : } else {
44 0 : header()->flags &= ~PUMPING_MSGS_BIT;
45 : }
46 0 : }
47 :
48 : // Call this if you always want to pump messages. You can call this method
49 : // or set_pump_messages_event but not both.
50 : void EnableMessagePumping();
51 :
52 0 : base::WaitableEvent* pump_messages_event() const {
53 0 : return pump_messages_event_;
54 : }
55 :
56 : // Returns true if the message is a reply to the given request id.
57 : static bool IsMessageReplyTo(const Message& msg, int request_id);
58 :
59 : // Given a reply message, returns an iterator to the beginning of the data
60 : // (i.e. skips over the synchronous specific data).
61 : static void* GetDataIterator(const Message* msg);
62 :
63 : // Given a synchronous message (or its reply), returns its id.
64 : static int GetMessageId(const Message& msg);
65 :
66 : // Generates a reply message to the given message.
67 : static Message* GenerateReply(const Message* msg);
68 :
69 : private:
70 : struct SyncHeader {
71 : // unique ID (unique per sender)
72 : int message_id;
73 : };
74 :
75 : static bool ReadSyncHeader(const Message& msg, SyncHeader* header);
76 : static bool WriteSyncHeader(Message* msg, const SyncHeader& header);
77 :
78 : MessageReplyDeserializer* deserializer_;
79 : base::WaitableEvent* pump_messages_event_;
80 :
81 : static uint32 next_id_; // for generation of unique ids
82 : };
83 :
84 : // Used to deserialize parameters from a reply to a synchronous message
85 : class MessageReplyDeserializer {
86 : public:
87 : bool SerializeOutputParameters(const Message& msg);
88 : private:
89 : // Derived classes need to implement this, using the given iterator (which
90 : // is skipped past the header for synchronous messages).
91 : virtual bool SerializeOutputParameters(const Message& msg, void* iter) = 0;
92 : };
93 :
94 : } // namespace IPC
95 :
96 : #endif // CHROME_COMMON_IPC_SYNC_MESSAGE_H__
|