blob: c9a1287a66d269ac1ebf1451cb62e4d8e28028d9 [file] [log] [blame]
jbates@chromium.org0fc87362012-03-08 05:42:56 +09001// Copyright (c) 2012 The Chromium Authors. All rights reserved.
agl@chromium.org1c6dcf22009-07-23 08:57:21 +09002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
jamesr@chromium.orgab4c65e2009-12-16 10:01:25 +09005#ifndef IPC_IPC_SYNC_MESSAGE_H_
6#define IPC_IPC_SYNC_MESSAGE_H_
agl@chromium.org1c6dcf22009-07-23 08:57:21 +09007
tfarina1cbfa082015-09-05 03:47:57 +09008#include <stdint.h>
danakjc3fb6c52016-04-23 13:21:09 +09009
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090010#if defined(OS_WIN)
11#include <windows.h>
12#endif
tfarina2d565d32015-09-16 18:56:21 +090013
danakjc3fb6c52016-04-23 13:21:09 +090014#include <memory>
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090015#include <string>
tfarina2d565d32015-09-16 18:56:21 +090016
avi42ebda42015-12-22 11:39:04 +090017#include "build/build_config.h"
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090018#include "ipc/ipc_message.h"
Ken Rockotb3a77c92017-09-14 13:23:41 +090019#include "ipc/ipc_message_support_export.h"
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090020
rockot39af2742017-03-25 03:36:44 +090021namespace base {
22class WaitableEvent;
23}
24
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090025namespace IPC {
26
27class MessageReplyDeserializer;
28
Ken Rockotb3a77c92017-09-14 13:23:41 +090029class IPC_MESSAGE_SUPPORT_EXPORT SyncMessage : public Message {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090030 public:
tfarina1cbfa082015-09-05 03:47:57 +090031 SyncMessage(int32_t routing_id,
32 uint32_t type,
33 PriorityValue priority,
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090034 MessageReplyDeserializer* deserializer);
dchengef7721a2014-10-22 11:29:52 +090035 ~SyncMessage() override;
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090036
37 // Call this to get a deserializer for the output parameters.
38 // Note that this can only be called once, and the caller is responsible
39 // for deleting the deserializer when they're done.
40 MessageReplyDeserializer* GetReplyDeserializer();
41
42 // If this message can cause the receiver to block while waiting for user
43 // input (i.e. by calling MessageBox), then the caller needs to pump window
44 // messages and dispatch asynchronous messages while waiting for the reply.
rockot0a321712016-07-08 05:26:02 +090045 // This call enables message pumping behavior while waiting for a reply to
46 // this message.
47 void EnableMessagePumping() {
48 header()->flags |= PUMPING_MSGS_BIT;
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090049 }
50
rockot0a321712016-07-08 05:26:02 +090051 // Indicates whether window messages should be pumped while waiting for a
52 // reply to this message.
53 bool ShouldPumpMessages() const {
54 return (header()->flags & PUMPING_MSGS_BIT) != 0;
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090055 }
56
57 // Returns true if the message is a reply to the given request id.
58 static bool IsMessageReplyTo(const Message& msg, int request_id);
59
60 // Given a reply message, returns an iterator to the beginning of the data
61 // (i.e. skips over the synchronous specific data).
brettwa4879472015-06-02 16:02:47 +090062 static base::PickleIterator GetDataIterator(const Message* msg);
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090063
64 // Given a synchronous message (or its reply), returns its id.
65 static int GetMessageId(const Message& msg);
66
67 // Generates a reply message to the given message.
68 static Message* GenerateReply(const Message* msg);
69
70 private:
71 struct SyncHeader {
72 // unique ID (unique per sender)
73 int message_id;
74 };
75
76 static bool ReadSyncHeader(const Message& msg, SyncHeader* header);
77 static bool WriteSyncHeader(Message* msg, const SyncHeader& header);
78
danakjc3fb6c52016-04-23 13:21:09 +090079 std::unique_ptr<MessageReplyDeserializer> deserializer_;
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090080};
81
82// Used to deserialize parameters from a reply to a synchronous message
Ken Rockotb3a77c92017-09-14 13:23:41 +090083class IPC_MESSAGE_SUPPORT_EXPORT MessageReplyDeserializer {
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090084 public:
jamesr@chromium.orgab4c65e2009-12-16 10:01:25 +090085 virtual ~MessageReplyDeserializer() {}
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090086 bool SerializeOutputParameters(const Message& msg);
87 private:
88 // Derived classes need to implement this, using the given iterator (which
89 // is skipped past the header for synchronous messages).
jbates@chromium.org0fc87362012-03-08 05:42:56 +090090 virtual bool SerializeOutputParameters(const Message& msg,
brettwa4879472015-06-02 16:02:47 +090091 base::PickleIterator iter) = 0;
agl@chromium.org1c6dcf22009-07-23 08:57:21 +090092};
93
jabdelmalek@google.comeb921652010-04-07 05:33:36 +090094// When sending a synchronous message, this structure contains an object
95// that knows how to deserialize the response.
96struct PendingSyncMsg {
rockot39af2742017-03-25 03:36:44 +090097 PendingSyncMsg(int id, MessageReplyDeserializer* d, base::WaitableEvent* e)
98 : id(id), deserializer(d), done_event(e), send_result(false) {}
rockot0a321712016-07-08 05:26:02 +090099
jabdelmalek@google.comeb921652010-04-07 05:33:36 +0900100 int id;
101 MessageReplyDeserializer* deserializer;
rockot39af2742017-03-25 03:36:44 +0900102 base::WaitableEvent* done_event;
jabdelmalek@google.comeb921652010-04-07 05:33:36 +0900103 bool send_result;
104};
105
agl@chromium.org1c6dcf22009-07-23 08:57:21 +0900106} // namespace IPC
107
jamesr@chromium.orgab4c65e2009-12-16 10:01:25 +0900108#endif // IPC_IPC_SYNC_MESSAGE_H_