blob: 7f0555134a222e8e88e44871cd70ed3c65e423bf [file] [log] [blame]
Hidehiko Abeb268b432018-04-24 01:37:19 +09001// 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
20namespace base {
21class WaitableEvent;
22}
23
24namespace IPC {
25
26class MessageReplyDeserializer;
27
28class IPC_EXPORT SyncMessage : public Message {
29 public:
30 SyncMessage(int32_t routing_id,
31 uint32_t type,
32 PriorityValue priority,
33 MessageReplyDeserializer* deserializer);
34 ~SyncMessage() override;
35
36 // Call this to get a deserializer for the output parameters.
37 // Note that this can only be called once, and the caller is responsible
38 // for deleting the deserializer when they're done.
39 MessageReplyDeserializer* GetReplyDeserializer();
40
41 // If this message can cause the receiver to block while waiting for user
42 // input (i.e. by calling MessageBox), then the caller needs to pump window
43 // messages and dispatch asynchronous messages while waiting for the reply.
44 // This call enables message pumping behavior while waiting for a reply to
45 // this message.
46 void EnableMessagePumping() {
47 header()->flags |= PUMPING_MSGS_BIT;
48 }
49
50 // Indicates whether window messages should be pumped while waiting for a
51 // reply to this message.
52 bool ShouldPumpMessages() const {
53 return (header()->flags & PUMPING_MSGS_BIT) != 0;
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 base::PickleIterator 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 std::unique_ptr<MessageReplyDeserializer> deserializer_;
79};
80
81// Used to deserialize parameters from a reply to a synchronous message
82class IPC_EXPORT MessageReplyDeserializer {
83 public:
84 virtual ~MessageReplyDeserializer() {}
85 bool SerializeOutputParameters(const Message& msg);
86 private:
87 // Derived classes need to implement this, using the given iterator (which
88 // is skipped past the header for synchronous messages).
89 virtual bool SerializeOutputParameters(const Message& msg,
90 base::PickleIterator iter) = 0;
91};
92
93// When sending a synchronous message, this structure contains an object
94// that knows how to deserialize the response.
95struct PendingSyncMsg {
96 PendingSyncMsg(int id, MessageReplyDeserializer* d, base::WaitableEvent* e)
97 : id(id), deserializer(d), done_event(e), send_result(false) {}
98
99 int id;
100 MessageReplyDeserializer* deserializer;
101 base::WaitableEvent* done_event;
102 bool send_result;
103};
104
105} // namespace IPC
106
107#endif // IPC_IPC_SYNC_MESSAGE_H_