ipc/chromium/src/chrome/common/ipc_message.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
michael@0 2 // Use of this source code is governed by a BSD-style license that can be
michael@0 3 // found in the LICENSE file.
michael@0 4
michael@0 5 #ifndef CHROME_COMMON_IPC_MESSAGE_H__
michael@0 6 #define CHROME_COMMON_IPC_MESSAGE_H__
michael@0 7
michael@0 8 #include <string>
michael@0 9
michael@0 10 #include "base/basictypes.h"
michael@0 11 #include "base/pickle.h"
michael@0 12
michael@0 13 #ifdef MOZ_TASK_TRACER
michael@0 14 #include "GeckoTaskTracer.h"
michael@0 15 #endif
michael@0 16
michael@0 17 #ifndef NDEBUG
michael@0 18 #define IPC_MESSAGE_LOG_ENABLED
michael@0 19 #endif
michael@0 20
michael@0 21 #if defined(OS_POSIX)
michael@0 22 #include "base/ref_counted.h"
michael@0 23 #endif
michael@0 24
michael@0 25 namespace base {
michael@0 26 struct FileDescriptor;
michael@0 27 }
michael@0 28
michael@0 29 class FileDescriptorSet;
michael@0 30
michael@0 31 namespace IPC {
michael@0 32
michael@0 33 //------------------------------------------------------------------------------
michael@0 34
michael@0 35 class Channel;
michael@0 36 class Message;
michael@0 37 struct LogData;
michael@0 38
michael@0 39 class Message : public Pickle {
michael@0 40 public:
michael@0 41 typedef uint32_t msgid_t;
michael@0 42
michael@0 43 // Implemented by objects that can send IPC messages across a channel.
michael@0 44 class Sender {
michael@0 45 public:
michael@0 46 virtual ~Sender() {}
michael@0 47
michael@0 48 // Sends the given IPC message. The implementor takes ownership of the
michael@0 49 // given Message regardless of whether or not this method succeeds. This
michael@0 50 // is done to make this method easier to use. Returns true on success and
michael@0 51 // false otherwise.
michael@0 52 virtual bool Send(Message* msg) = 0;
michael@0 53 };
michael@0 54
michael@0 55 enum PriorityValue {
michael@0 56 PRIORITY_LOW = 1,
michael@0 57 PRIORITY_NORMAL,
michael@0 58 PRIORITY_HIGH
michael@0 59 };
michael@0 60
michael@0 61 enum MessageCompression {
michael@0 62 COMPRESSION_NONE,
michael@0 63 COMPRESSION_ENABLED
michael@0 64 };
michael@0 65
michael@0 66 virtual ~Message();
michael@0 67
michael@0 68 Message();
michael@0 69
michael@0 70 // Initialize a message with a user-defined type, priority value, and
michael@0 71 // destination WebView ID.
michael@0 72 Message(int32_t routing_id, msgid_t type, PriorityValue priority,
michael@0 73 MessageCompression compression = COMPRESSION_NONE,
michael@0 74 const char* const name="???");
michael@0 75
michael@0 76 // Initializes a message from a const block of data. The data is not copied;
michael@0 77 // instead the data is merely referenced by this message. Only const methods
michael@0 78 // should be used on the message when initialized this way.
michael@0 79 Message(const char* data, int data_len);
michael@0 80
michael@0 81 Message(const Message& other);
michael@0 82 Message& operator=(const Message& other);
michael@0 83
michael@0 84 PriorityValue priority() const {
michael@0 85 return static_cast<PriorityValue>(header()->flags & PRIORITY_MASK);
michael@0 86 }
michael@0 87
michael@0 88 // True if this is a synchronous message.
michael@0 89 bool is_sync() const {
michael@0 90 return (header()->flags & SYNC_BIT) != 0;
michael@0 91 }
michael@0 92
michael@0 93 // True if this is a synchronous message.
michael@0 94 bool is_interrupt() const {
michael@0 95 return (header()->flags & INTERRUPT_BIT) != 0;
michael@0 96 }
michael@0 97
michael@0 98 // True if this is an urgent message.
michael@0 99 bool is_urgent() const {
michael@0 100 return (header()->flags & URGENT_BIT) != 0;
michael@0 101 }
michael@0 102
michael@0 103 // True if this is an RPC message.
michael@0 104 bool is_rpc() const {
michael@0 105 return (header()->flags & RPC_BIT) != 0;
michael@0 106 }
michael@0 107
michael@0 108 // True if compression is enabled for this message.
michael@0 109 bool compress() const {
michael@0 110 return (header()->flags & COMPRESS_BIT) != 0;
michael@0 111 }
michael@0 112
michael@0 113 // Set this on a reply to a synchronous message.
michael@0 114 void set_reply() {
michael@0 115 header()->flags |= REPLY_BIT;
michael@0 116 }
michael@0 117
michael@0 118 bool is_reply() const {
michael@0 119 return (header()->flags & REPLY_BIT) != 0;
michael@0 120 }
michael@0 121
michael@0 122 // Set this on a reply to a synchronous message to indicate that no receiver
michael@0 123 // was found.
michael@0 124 void set_reply_error() {
michael@0 125 header()->flags |= REPLY_ERROR_BIT;
michael@0 126 }
michael@0 127
michael@0 128 bool is_reply_error() const {
michael@0 129 return (header()->flags & REPLY_ERROR_BIT) != 0;
michael@0 130 }
michael@0 131
michael@0 132 // Normally when a receiver gets a message and they're blocked on a
michael@0 133 // synchronous message Send, they buffer a message. Setting this flag causes
michael@0 134 // the receiver to be unblocked and the message to be dispatched immediately.
michael@0 135 void set_unblock(bool unblock) {
michael@0 136 if (unblock) {
michael@0 137 header()->flags |= UNBLOCK_BIT;
michael@0 138 } else {
michael@0 139 header()->flags &= ~UNBLOCK_BIT;
michael@0 140 }
michael@0 141 }
michael@0 142
michael@0 143 bool should_unblock() const {
michael@0 144 return (header()->flags & UNBLOCK_BIT) != 0;
michael@0 145 }
michael@0 146
michael@0 147 // Tells the receiver that the caller is pumping messages while waiting
michael@0 148 // for the result.
michael@0 149 bool is_caller_pumping_messages() const {
michael@0 150 return (header()->flags & PUMPING_MSGS_BIT) != 0;
michael@0 151 }
michael@0 152
michael@0 153 msgid_t type() const {
michael@0 154 return header()->type;
michael@0 155 }
michael@0 156
michael@0 157 int32_t routing_id() const {
michael@0 158 return header()->routing;
michael@0 159 }
michael@0 160
michael@0 161 void set_routing_id(int32_t new_id) {
michael@0 162 header()->routing = new_id;
michael@0 163 }
michael@0 164
michael@0 165 int32_t transaction_id() const {
michael@0 166 return header()->txid;
michael@0 167 }
michael@0 168
michael@0 169 void set_transaction_id(int32_t txid) {
michael@0 170 header()->txid = txid;
michael@0 171 }
michael@0 172
michael@0 173 uint32_t interrupt_remote_stack_depth_guess() const {
michael@0 174 return header()->interrupt_remote_stack_depth_guess;
michael@0 175 }
michael@0 176
michael@0 177 void set_interrupt_remote_stack_depth_guess(uint32_t depth) {
michael@0 178 DCHECK(is_interrupt());
michael@0 179 header()->interrupt_remote_stack_depth_guess = depth;
michael@0 180 }
michael@0 181
michael@0 182 uint32_t interrupt_local_stack_depth() const {
michael@0 183 return header()->interrupt_local_stack_depth;
michael@0 184 }
michael@0 185
michael@0 186 void set_interrupt_local_stack_depth(uint32_t depth) {
michael@0 187 DCHECK(is_interrupt());
michael@0 188 header()->interrupt_local_stack_depth = depth;
michael@0 189 }
michael@0 190
michael@0 191 int32_t seqno() const {
michael@0 192 return header()->seqno;
michael@0 193 }
michael@0 194
michael@0 195 void set_seqno(int32_t seqno) {
michael@0 196 header()->seqno = seqno;
michael@0 197 }
michael@0 198
michael@0 199 const char* const name() const {
michael@0 200 return name_;
michael@0 201 }
michael@0 202
michael@0 203 void set_name(const char* const name) {
michael@0 204 name_ = name;
michael@0 205 }
michael@0 206
michael@0 207 template<class T>
michael@0 208 static bool Dispatch(const Message* msg, T* obj, void (T::*func)()) {
michael@0 209 (obj->*func)();
michael@0 210 return true;
michael@0 211 }
michael@0 212
michael@0 213 template<class T>
michael@0 214 static bool Dispatch(const Message* msg, T* obj, void (T::*func)() const) {
michael@0 215 (obj->*func)();
michael@0 216 return true;
michael@0 217 }
michael@0 218
michael@0 219 template<class T>
michael@0 220 static bool Dispatch(const Message* msg, T* obj,
michael@0 221 void (T::*func)(const Message&)) {
michael@0 222 (obj->*func)(*msg);
michael@0 223 return true;
michael@0 224 }
michael@0 225
michael@0 226 template<class T>
michael@0 227 static bool Dispatch(const Message* msg, T* obj,
michael@0 228 void (T::*func)(const Message&) const) {
michael@0 229 (obj->*func)(*msg);
michael@0 230 return true;
michael@0 231 }
michael@0 232
michael@0 233 // Used for async messages with no parameters.
michael@0 234 static void Log(const Message* msg, std::wstring* l) {
michael@0 235 }
michael@0 236
michael@0 237 // Find the end of the message data that starts at range_start. Returns NULL
michael@0 238 // if the entire message is not found in the given data range.
michael@0 239 static const char* FindNext(const char* range_start, const char* range_end) {
michael@0 240 return Pickle::FindNext(sizeof(Header), range_start, range_end);
michael@0 241 }
michael@0 242
michael@0 243 #if defined(OS_POSIX)
michael@0 244 // On POSIX, a message supports reading / writing FileDescriptor objects.
michael@0 245 // This is used to pass a file descriptor to the peer of an IPC channel.
michael@0 246
michael@0 247 // Add a descriptor to the end of the set. Returns false iff the set is full.
michael@0 248 bool WriteFileDescriptor(const base::FileDescriptor& descriptor);
michael@0 249 // Get a file descriptor from the message. Returns false on error.
michael@0 250 // iter: a Pickle iterator to the current location in the message.
michael@0 251 bool ReadFileDescriptor(void** iter, base::FileDescriptor* descriptor) const;
michael@0 252
michael@0 253 #if defined(OS_MACOSX)
michael@0 254 void set_fd_cookie(uint32_t cookie) {
michael@0 255 header()->cookie = cookie;
michael@0 256 }
michael@0 257 uint32_t fd_cookie() const {
michael@0 258 return header()->cookie;
michael@0 259 }
michael@0 260 #endif
michael@0 261 #endif
michael@0 262
michael@0 263 #ifdef IPC_MESSAGE_LOG_ENABLED
michael@0 264 // Adds the outgoing time from Time::Now() at the end of the message and sets
michael@0 265 // a bit to indicate that it's been added.
michael@0 266 void set_sent_time(int64_t time);
michael@0 267 int64_t sent_time() const;
michael@0 268
michael@0 269 void set_received_time(int64_t time) const;
michael@0 270 int64_t received_time() const { return received_time_; }
michael@0 271 void set_output_params(const std::wstring& op) const { output_params_ = op; }
michael@0 272 const std::wstring& output_params() const { return output_params_; }
michael@0 273 // The following four functions are needed so we can log sync messages with
michael@0 274 // delayed replies. We stick the log data from the sent message into the
michael@0 275 // reply message, so that when it's sent and we have the output parameters
michael@0 276 // we can log it. As such, we set a flag on the sent message to not log it.
michael@0 277 void set_sync_log_data(LogData* data) const { log_data_ = data; }
michael@0 278 LogData* sync_log_data() const { return log_data_; }
michael@0 279 void set_dont_log() const { dont_log_ = true; }
michael@0 280 bool dont_log() const { return dont_log_; }
michael@0 281 #endif
michael@0 282
michael@0 283 friend class Channel;
michael@0 284 friend class MessageReplyDeserializer;
michael@0 285 friend class SyncMessage;
michael@0 286
michael@0 287 void set_sync() {
michael@0 288 header()->flags |= SYNC_BIT;
michael@0 289 }
michael@0 290
michael@0 291 void set_interrupt() {
michael@0 292 header()->flags |= INTERRUPT_BIT;
michael@0 293 }
michael@0 294
michael@0 295 void set_urgent() {
michael@0 296 header()->flags |= URGENT_BIT;
michael@0 297 }
michael@0 298
michael@0 299 void set_rpc() {
michael@0 300 header()->flags |= RPC_BIT;
michael@0 301 }
michael@0 302
michael@0 303 #if !defined(OS_MACOSX)
michael@0 304 protected:
michael@0 305 #endif
michael@0 306
michael@0 307 // flags
michael@0 308 enum {
michael@0 309 PRIORITY_MASK = 0x0003,
michael@0 310 SYNC_BIT = 0x0004,
michael@0 311 REPLY_BIT = 0x0008,
michael@0 312 REPLY_ERROR_BIT = 0x0010,
michael@0 313 UNBLOCK_BIT = 0x0020,
michael@0 314 PUMPING_MSGS_BIT= 0x0040,
michael@0 315 HAS_SENT_TIME_BIT = 0x0080,
michael@0 316 INTERRUPT_BIT = 0x0100,
michael@0 317 COMPRESS_BIT = 0x0200,
michael@0 318 URGENT_BIT = 0x0400,
michael@0 319 RPC_BIT = 0x0800
michael@0 320 };
michael@0 321
michael@0 322 struct Header : Pickle::Header {
michael@0 323 int32_t routing; // ID of the view that this message is destined for
michael@0 324 msgid_t type; // specifies the user-defined message type
michael@0 325 uint32_t flags; // specifies control flags for the message
michael@0 326 #if defined(OS_POSIX)
michael@0 327 uint32_t num_fds; // the number of descriptors included with this message
michael@0 328 # if defined(OS_MACOSX)
michael@0 329 uint32_t cookie; // cookie to ACK that the descriptors have been read.
michael@0 330 # endif
michael@0 331 #endif
michael@0 332 union {
michael@0 333 // For Interrupt messages, a guess at what the *other* side's stack depth is.
michael@0 334 uint32_t interrupt_remote_stack_depth_guess;
michael@0 335
michael@0 336 // For RPC and Urgent messages, a transaction ID for message ordering.
michael@0 337 int32_t txid;
michael@0 338 };
michael@0 339 // The actual local stack depth.
michael@0 340 uint32_t interrupt_local_stack_depth;
michael@0 341 // Sequence number
michael@0 342 int32_t seqno;
michael@0 343 #ifdef MOZ_TASK_TRACER
michael@0 344 uint64_t source_event_id;
michael@0 345 uint64_t parent_task_id;
michael@0 346 mozilla::tasktracer::SourceEventType source_event_type;
michael@0 347 #endif
michael@0 348 };
michael@0 349
michael@0 350 Header* header() {
michael@0 351 return headerT<Header>();
michael@0 352 }
michael@0 353 const Header* header() const {
michael@0 354 return headerT<Header>();
michael@0 355 }
michael@0 356
michael@0 357 void InitLoggingVariables(const char* const name="???");
michael@0 358
michael@0 359 #if defined(OS_POSIX)
michael@0 360 // The set of file descriptors associated with this message.
michael@0 361 scoped_refptr<FileDescriptorSet> file_descriptor_set_;
michael@0 362
michael@0 363 // Ensure that a FileDescriptorSet is allocated
michael@0 364 void EnsureFileDescriptorSet();
michael@0 365
michael@0 366 FileDescriptorSet* file_descriptor_set() {
michael@0 367 EnsureFileDescriptorSet();
michael@0 368 return file_descriptor_set_.get();
michael@0 369 }
michael@0 370 const FileDescriptorSet* file_descriptor_set() const {
michael@0 371 return file_descriptor_set_.get();
michael@0 372 }
michael@0 373 #endif
michael@0 374
michael@0 375 const char* name_;
michael@0 376
michael@0 377 #ifdef IPC_MESSAGE_LOG_ENABLED
michael@0 378 // Used for logging.
michael@0 379 mutable int64_t received_time_;
michael@0 380 mutable std::wstring output_params_;
michael@0 381 mutable LogData* log_data_;
michael@0 382 mutable bool dont_log_;
michael@0 383 #endif
michael@0 384 };
michael@0 385
michael@0 386 //------------------------------------------------------------------------------
michael@0 387
michael@0 388 } // namespace IPC
michael@0 389
michael@0 390 enum SpecialRoutingIDs {
michael@0 391 // indicates that we don't have a routing ID yet.
michael@0 392 MSG_ROUTING_NONE = kint32min,
michael@0 393
michael@0 394 // indicates a general message not sent to a particular tab.
michael@0 395 MSG_ROUTING_CONTROL = kint32max
michael@0 396 };
michael@0 397
michael@0 398 #define IPC_REPLY_ID 0xFFF0 // Special message id for replies
michael@0 399 #define IPC_LOGGING_ID 0xFFF1 // Special message id for logging
michael@0 400
michael@0 401 #endif // CHROME_COMMON_IPC_MESSAGE_H__

mercurial