1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/ipc/chromium/src/chrome/common/ipc_message.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,401 @@ 1.4 +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 + 1.8 +#ifndef CHROME_COMMON_IPC_MESSAGE_H__ 1.9 +#define CHROME_COMMON_IPC_MESSAGE_H__ 1.10 + 1.11 +#include <string> 1.12 + 1.13 +#include "base/basictypes.h" 1.14 +#include "base/pickle.h" 1.15 + 1.16 +#ifdef MOZ_TASK_TRACER 1.17 +#include "GeckoTaskTracer.h" 1.18 +#endif 1.19 + 1.20 +#ifndef NDEBUG 1.21 +#define IPC_MESSAGE_LOG_ENABLED 1.22 +#endif 1.23 + 1.24 +#if defined(OS_POSIX) 1.25 +#include "base/ref_counted.h" 1.26 +#endif 1.27 + 1.28 +namespace base { 1.29 +struct FileDescriptor; 1.30 +} 1.31 + 1.32 +class FileDescriptorSet; 1.33 + 1.34 +namespace IPC { 1.35 + 1.36 +//------------------------------------------------------------------------------ 1.37 + 1.38 +class Channel; 1.39 +class Message; 1.40 +struct LogData; 1.41 + 1.42 +class Message : public Pickle { 1.43 + public: 1.44 + typedef uint32_t msgid_t; 1.45 + 1.46 + // Implemented by objects that can send IPC messages across a channel. 1.47 + class Sender { 1.48 + public: 1.49 + virtual ~Sender() {} 1.50 + 1.51 + // Sends the given IPC message. The implementor takes ownership of the 1.52 + // given Message regardless of whether or not this method succeeds. This 1.53 + // is done to make this method easier to use. Returns true on success and 1.54 + // false otherwise. 1.55 + virtual bool Send(Message* msg) = 0; 1.56 + }; 1.57 + 1.58 + enum PriorityValue { 1.59 + PRIORITY_LOW = 1, 1.60 + PRIORITY_NORMAL, 1.61 + PRIORITY_HIGH 1.62 + }; 1.63 + 1.64 + enum MessageCompression { 1.65 + COMPRESSION_NONE, 1.66 + COMPRESSION_ENABLED 1.67 + }; 1.68 + 1.69 + virtual ~Message(); 1.70 + 1.71 + Message(); 1.72 + 1.73 + // Initialize a message with a user-defined type, priority value, and 1.74 + // destination WebView ID. 1.75 + Message(int32_t routing_id, msgid_t type, PriorityValue priority, 1.76 + MessageCompression compression = COMPRESSION_NONE, 1.77 + const char* const name="???"); 1.78 + 1.79 + // Initializes a message from a const block of data. The data is not copied; 1.80 + // instead the data is merely referenced by this message. Only const methods 1.81 + // should be used on the message when initialized this way. 1.82 + Message(const char* data, int data_len); 1.83 + 1.84 + Message(const Message& other); 1.85 + Message& operator=(const Message& other); 1.86 + 1.87 + PriorityValue priority() const { 1.88 + return static_cast<PriorityValue>(header()->flags & PRIORITY_MASK); 1.89 + } 1.90 + 1.91 + // True if this is a synchronous message. 1.92 + bool is_sync() const { 1.93 + return (header()->flags & SYNC_BIT) != 0; 1.94 + } 1.95 + 1.96 + // True if this is a synchronous message. 1.97 + bool is_interrupt() const { 1.98 + return (header()->flags & INTERRUPT_BIT) != 0; 1.99 + } 1.100 + 1.101 + // True if this is an urgent message. 1.102 + bool is_urgent() const { 1.103 + return (header()->flags & URGENT_BIT) != 0; 1.104 + } 1.105 + 1.106 + // True if this is an RPC message. 1.107 + bool is_rpc() const { 1.108 + return (header()->flags & RPC_BIT) != 0; 1.109 + } 1.110 + 1.111 + // True if compression is enabled for this message. 1.112 + bool compress() const { 1.113 + return (header()->flags & COMPRESS_BIT) != 0; 1.114 + } 1.115 + 1.116 + // Set this on a reply to a synchronous message. 1.117 + void set_reply() { 1.118 + header()->flags |= REPLY_BIT; 1.119 + } 1.120 + 1.121 + bool is_reply() const { 1.122 + return (header()->flags & REPLY_BIT) != 0; 1.123 + } 1.124 + 1.125 + // Set this on a reply to a synchronous message to indicate that no receiver 1.126 + // was found. 1.127 + void set_reply_error() { 1.128 + header()->flags |= REPLY_ERROR_BIT; 1.129 + } 1.130 + 1.131 + bool is_reply_error() const { 1.132 + return (header()->flags & REPLY_ERROR_BIT) != 0; 1.133 + } 1.134 + 1.135 + // Normally when a receiver gets a message and they're blocked on a 1.136 + // synchronous message Send, they buffer a message. Setting this flag causes 1.137 + // the receiver to be unblocked and the message to be dispatched immediately. 1.138 + void set_unblock(bool unblock) { 1.139 + if (unblock) { 1.140 + header()->flags |= UNBLOCK_BIT; 1.141 + } else { 1.142 + header()->flags &= ~UNBLOCK_BIT; 1.143 + } 1.144 + } 1.145 + 1.146 + bool should_unblock() const { 1.147 + return (header()->flags & UNBLOCK_BIT) != 0; 1.148 + } 1.149 + 1.150 + // Tells the receiver that the caller is pumping messages while waiting 1.151 + // for the result. 1.152 + bool is_caller_pumping_messages() const { 1.153 + return (header()->flags & PUMPING_MSGS_BIT) != 0; 1.154 + } 1.155 + 1.156 + msgid_t type() const { 1.157 + return header()->type; 1.158 + } 1.159 + 1.160 + int32_t routing_id() const { 1.161 + return header()->routing; 1.162 + } 1.163 + 1.164 + void set_routing_id(int32_t new_id) { 1.165 + header()->routing = new_id; 1.166 + } 1.167 + 1.168 + int32_t transaction_id() const { 1.169 + return header()->txid; 1.170 + } 1.171 + 1.172 + void set_transaction_id(int32_t txid) { 1.173 + header()->txid = txid; 1.174 + } 1.175 + 1.176 + uint32_t interrupt_remote_stack_depth_guess() const { 1.177 + return header()->interrupt_remote_stack_depth_guess; 1.178 + } 1.179 + 1.180 + void set_interrupt_remote_stack_depth_guess(uint32_t depth) { 1.181 + DCHECK(is_interrupt()); 1.182 + header()->interrupt_remote_stack_depth_guess = depth; 1.183 + } 1.184 + 1.185 + uint32_t interrupt_local_stack_depth() const { 1.186 + return header()->interrupt_local_stack_depth; 1.187 + } 1.188 + 1.189 + void set_interrupt_local_stack_depth(uint32_t depth) { 1.190 + DCHECK(is_interrupt()); 1.191 + header()->interrupt_local_stack_depth = depth; 1.192 + } 1.193 + 1.194 + int32_t seqno() const { 1.195 + return header()->seqno; 1.196 + } 1.197 + 1.198 + void set_seqno(int32_t seqno) { 1.199 + header()->seqno = seqno; 1.200 + } 1.201 + 1.202 + const char* const name() const { 1.203 + return name_; 1.204 + } 1.205 + 1.206 + void set_name(const char* const name) { 1.207 + name_ = name; 1.208 + } 1.209 + 1.210 + template<class T> 1.211 + static bool Dispatch(const Message* msg, T* obj, void (T::*func)()) { 1.212 + (obj->*func)(); 1.213 + return true; 1.214 + } 1.215 + 1.216 + template<class T> 1.217 + static bool Dispatch(const Message* msg, T* obj, void (T::*func)() const) { 1.218 + (obj->*func)(); 1.219 + return true; 1.220 + } 1.221 + 1.222 + template<class T> 1.223 + static bool Dispatch(const Message* msg, T* obj, 1.224 + void (T::*func)(const Message&)) { 1.225 + (obj->*func)(*msg); 1.226 + return true; 1.227 + } 1.228 + 1.229 + template<class T> 1.230 + static bool Dispatch(const Message* msg, T* obj, 1.231 + void (T::*func)(const Message&) const) { 1.232 + (obj->*func)(*msg); 1.233 + return true; 1.234 + } 1.235 + 1.236 + // Used for async messages with no parameters. 1.237 + static void Log(const Message* msg, std::wstring* l) { 1.238 + } 1.239 + 1.240 + // Find the end of the message data that starts at range_start. Returns NULL 1.241 + // if the entire message is not found in the given data range. 1.242 + static const char* FindNext(const char* range_start, const char* range_end) { 1.243 + return Pickle::FindNext(sizeof(Header), range_start, range_end); 1.244 + } 1.245 + 1.246 +#if defined(OS_POSIX) 1.247 + // On POSIX, a message supports reading / writing FileDescriptor objects. 1.248 + // This is used to pass a file descriptor to the peer of an IPC channel. 1.249 + 1.250 + // Add a descriptor to the end of the set. Returns false iff the set is full. 1.251 + bool WriteFileDescriptor(const base::FileDescriptor& descriptor); 1.252 + // Get a file descriptor from the message. Returns false on error. 1.253 + // iter: a Pickle iterator to the current location in the message. 1.254 + bool ReadFileDescriptor(void** iter, base::FileDescriptor* descriptor) const; 1.255 + 1.256 +#if defined(OS_MACOSX) 1.257 + void set_fd_cookie(uint32_t cookie) { 1.258 + header()->cookie = cookie; 1.259 + } 1.260 + uint32_t fd_cookie() const { 1.261 + return header()->cookie; 1.262 + } 1.263 +#endif 1.264 +#endif 1.265 + 1.266 +#ifdef IPC_MESSAGE_LOG_ENABLED 1.267 + // Adds the outgoing time from Time::Now() at the end of the message and sets 1.268 + // a bit to indicate that it's been added. 1.269 + void set_sent_time(int64_t time); 1.270 + int64_t sent_time() const; 1.271 + 1.272 + void set_received_time(int64_t time) const; 1.273 + int64_t received_time() const { return received_time_; } 1.274 + void set_output_params(const std::wstring& op) const { output_params_ = op; } 1.275 + const std::wstring& output_params() const { return output_params_; } 1.276 + // The following four functions are needed so we can log sync messages with 1.277 + // delayed replies. We stick the log data from the sent message into the 1.278 + // reply message, so that when it's sent and we have the output parameters 1.279 + // we can log it. As such, we set a flag on the sent message to not log it. 1.280 + void set_sync_log_data(LogData* data) const { log_data_ = data; } 1.281 + LogData* sync_log_data() const { return log_data_; } 1.282 + void set_dont_log() const { dont_log_ = true; } 1.283 + bool dont_log() const { return dont_log_; } 1.284 +#endif 1.285 + 1.286 + friend class Channel; 1.287 + friend class MessageReplyDeserializer; 1.288 + friend class SyncMessage; 1.289 + 1.290 + void set_sync() { 1.291 + header()->flags |= SYNC_BIT; 1.292 + } 1.293 + 1.294 + void set_interrupt() { 1.295 + header()->flags |= INTERRUPT_BIT; 1.296 + } 1.297 + 1.298 + void set_urgent() { 1.299 + header()->flags |= URGENT_BIT; 1.300 + } 1.301 + 1.302 + void set_rpc() { 1.303 + header()->flags |= RPC_BIT; 1.304 + } 1.305 + 1.306 +#if !defined(OS_MACOSX) 1.307 + protected: 1.308 +#endif 1.309 + 1.310 + // flags 1.311 + enum { 1.312 + PRIORITY_MASK = 0x0003, 1.313 + SYNC_BIT = 0x0004, 1.314 + REPLY_BIT = 0x0008, 1.315 + REPLY_ERROR_BIT = 0x0010, 1.316 + UNBLOCK_BIT = 0x0020, 1.317 + PUMPING_MSGS_BIT= 0x0040, 1.318 + HAS_SENT_TIME_BIT = 0x0080, 1.319 + INTERRUPT_BIT = 0x0100, 1.320 + COMPRESS_BIT = 0x0200, 1.321 + URGENT_BIT = 0x0400, 1.322 + RPC_BIT = 0x0800 1.323 + }; 1.324 + 1.325 + struct Header : Pickle::Header { 1.326 + int32_t routing; // ID of the view that this message is destined for 1.327 + msgid_t type; // specifies the user-defined message type 1.328 + uint32_t flags; // specifies control flags for the message 1.329 +#if defined(OS_POSIX) 1.330 + uint32_t num_fds; // the number of descriptors included with this message 1.331 +# if defined(OS_MACOSX) 1.332 + uint32_t cookie; // cookie to ACK that the descriptors have been read. 1.333 +# endif 1.334 +#endif 1.335 + union { 1.336 + // For Interrupt messages, a guess at what the *other* side's stack depth is. 1.337 + uint32_t interrupt_remote_stack_depth_guess; 1.338 + 1.339 + // For RPC and Urgent messages, a transaction ID for message ordering. 1.340 + int32_t txid; 1.341 + }; 1.342 + // The actual local stack depth. 1.343 + uint32_t interrupt_local_stack_depth; 1.344 + // Sequence number 1.345 + int32_t seqno; 1.346 +#ifdef MOZ_TASK_TRACER 1.347 + uint64_t source_event_id; 1.348 + uint64_t parent_task_id; 1.349 + mozilla::tasktracer::SourceEventType source_event_type; 1.350 +#endif 1.351 + }; 1.352 + 1.353 + Header* header() { 1.354 + return headerT<Header>(); 1.355 + } 1.356 + const Header* header() const { 1.357 + return headerT<Header>(); 1.358 + } 1.359 + 1.360 + void InitLoggingVariables(const char* const name="???"); 1.361 + 1.362 +#if defined(OS_POSIX) 1.363 + // The set of file descriptors associated with this message. 1.364 + scoped_refptr<FileDescriptorSet> file_descriptor_set_; 1.365 + 1.366 + // Ensure that a FileDescriptorSet is allocated 1.367 + void EnsureFileDescriptorSet(); 1.368 + 1.369 + FileDescriptorSet* file_descriptor_set() { 1.370 + EnsureFileDescriptorSet(); 1.371 + return file_descriptor_set_.get(); 1.372 + } 1.373 + const FileDescriptorSet* file_descriptor_set() const { 1.374 + return file_descriptor_set_.get(); 1.375 + } 1.376 +#endif 1.377 + 1.378 + const char* name_; 1.379 + 1.380 +#ifdef IPC_MESSAGE_LOG_ENABLED 1.381 + // Used for logging. 1.382 + mutable int64_t received_time_; 1.383 + mutable std::wstring output_params_; 1.384 + mutable LogData* log_data_; 1.385 + mutable bool dont_log_; 1.386 +#endif 1.387 +}; 1.388 + 1.389 +//------------------------------------------------------------------------------ 1.390 + 1.391 +} // namespace IPC 1.392 + 1.393 +enum SpecialRoutingIDs { 1.394 + // indicates that we don't have a routing ID yet. 1.395 + MSG_ROUTING_NONE = kint32min, 1.396 + 1.397 + // indicates a general message not sent to a particular tab. 1.398 + MSG_ROUTING_CONTROL = kint32max 1.399 +}; 1.400 + 1.401 +#define IPC_REPLY_ID 0xFFF0 // Special message id for replies 1.402 +#define IPC_LOGGING_ID 0xFFF1 // Special message id for logging 1.403 + 1.404 +#endif // CHROME_COMMON_IPC_MESSAGE_H__