LCOV - code coverage report
Current view: top level - ipc/chromium/src/chrome/common - ipc_message.h (source / functions) Hit Total Coverage
Test: output.info Lines: 59 85 69.4 %
Date: 2017-07-14 16:53:18 Functions: 24 34 70.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
       4             : // Use of this source code is governed by a BSD-style license that can be
       5             : // found in the LICENSE file.
       6             : 
       7             : #ifndef CHROME_COMMON_IPC_MESSAGE_H__
       8             : #define CHROME_COMMON_IPC_MESSAGE_H__
       9             : 
      10             : #include <string>
      11             : 
      12             : #include "base/basictypes.h"
      13             : #include "base/pickle.h"
      14             : #include "mozilla/TimeStamp.h"
      15             : 
      16             : #ifdef MOZ_TASK_TRACER
      17             : #include "GeckoTaskTracer.h"
      18             : #endif
      19             : 
      20             : #if defined(OS_POSIX)
      21             : #include "nsAutoPtr.h"
      22             : #endif
      23             : 
      24             : namespace base {
      25             : struct FileDescriptor;
      26             : }
      27             : 
      28             : class FileDescriptorSet;
      29             : 
      30             : namespace IPC {
      31             : 
      32             : //------------------------------------------------------------------------------
      33             : 
      34             : class Channel;
      35             : class Message;
      36             : struct LogData;
      37             : 
      38             : class Message : public Pickle {
      39             :  public:
      40             :   typedef uint32_t msgid_t;
      41             : 
      42             :   enum NestedLevel {
      43             :     NOT_NESTED = 1,
      44             :     NESTED_INSIDE_SYNC = 2,
      45             :     NESTED_INSIDE_CPOW = 3
      46             :   };
      47             : 
      48             :   enum PriorityValue {
      49             :     NORMAL_PRIORITY,
      50             :     HIGH_PRIORITY,
      51             :   };
      52             : 
      53             :   enum MessageCompression {
      54             :     COMPRESSION_NONE,
      55             :     COMPRESSION_ENABLED,
      56             :     COMPRESSION_ALL
      57             :   };
      58             : 
      59             :   virtual ~Message();
      60             : 
      61             :   Message();
      62             : 
      63             :   // Initialize a message with a user-defined type, priority value, and
      64             :   // destination WebView ID.
      65             :   //
      66             :   // NOTE: `recordWriteLatency` is only passed by IPDL generated message code,
      67             :   // and is used to trigger the IPC_WRITE_LATENCY_MS telemetry.
      68             :   Message(int32_t routing_id,
      69             :           msgid_t type,
      70             :           uint32_t segmentCapacity = 0, // 0 for the default capacity.
      71             :           NestedLevel nestedLevel = NOT_NESTED,
      72             :           PriorityValue priority = NORMAL_PRIORITY,
      73             :           MessageCompression compression = COMPRESSION_NONE,
      74             :           const char* const name="???",
      75             :           bool recordWriteLatency=false);
      76             : 
      77             :   Message(const char* data, int data_len);
      78             : 
      79             :   Message(const Message& other) = delete;
      80             :   Message(Message&& other);
      81             :   Message& operator=(const Message& other) = delete;
      82             :   Message& operator=(Message&& other);
      83             : 
      84        2513 :   NestedLevel nested_level() const {
      85        2513 :     return static_cast<NestedLevel>(header()->flags & NESTED_MASK);
      86             :   }
      87             : 
      88           0 :   void set_nested_level(NestedLevel nestedLevel) {
      89           0 :     DCHECK((nestedLevel & ~NESTED_MASK) == 0);
      90           0 :     header()->flags = (header()->flags & ~NESTED_MASK) | nestedLevel;
      91           0 :   }
      92             : 
      93         307 :   PriorityValue priority() const {
      94         307 :     if (header()->flags & PRIO_BIT) {
      95          36 :       return HIGH_PRIORITY;
      96             :     }
      97         271 :     return NORMAL_PRIORITY;
      98             :   }
      99             : 
     100             :   void set_priority(PriorityValue prio) {
     101             :     header()->flags &= ~PRIO_BIT;
     102             :     if (prio == HIGH_PRIORITY) {
     103             :       header()->flags |= PRIO_BIT;
     104             :     }
     105             :   }
     106             : 
     107         471 :   bool is_constructor() const {
     108         471 :     return (header()->flags & CONSTRUCTOR_BIT) != 0;
     109             :   }
     110             : 
     111          38 :   void set_constructor() {
     112          38 :     header()->flags |= CONSTRUCTOR_BIT;
     113          38 :   }
     114             : 
     115             :   // True if this is a synchronous message.
     116        4832 :   bool is_sync() const {
     117        4832 :     return (header()->flags & SYNC_BIT) != 0;
     118             :   }
     119             : 
     120             :   // True if this is a synchronous message.
     121        1880 :   bool is_interrupt() const {
     122        1880 :     return (header()->flags & INTERRUPT_BIT) != 0;
     123             :   }
     124             : 
     125             :   // True if compression is enabled for this message.
     126        1571 :   MessageCompression compress_type() const {
     127        2967 :     return (header()->flags & COMPRESS_BIT) ?
     128             :                COMPRESSION_ENABLED :
     129        1396 :                (header()->flags & COMPRESSALL_BIT) ?
     130             :                    COMPRESSION_ALL :
     131        1571 :                    COMPRESSION_NONE;
     132             :   }
     133             : 
     134             :   // Set this on a reply to a synchronous message.
     135           3 :   void set_reply() {
     136           3 :     header()->flags |= REPLY_BIT;
     137           3 :   }
     138             : 
     139           9 :   bool is_reply() const {
     140           9 :     return (header()->flags & REPLY_BIT) != 0;
     141             :   }
     142             : 
     143             :   // Set this on a reply to a synchronous message to indicate that no receiver
     144             :   // was found.
     145           0 :   void set_reply_error() {
     146           0 :     header()->flags |= REPLY_ERROR_BIT;
     147           0 :   }
     148             : 
     149           6 :   bool is_reply_error() const {
     150           6 :     return (header()->flags & REPLY_ERROR_BIT) != 0;
     151             :   }
     152             : 
     153        2506 :   msgid_t type() const {
     154        2506 :     return header()->type;
     155             :   }
     156             : 
     157        3897 :   int32_t routing_id() const {
     158        3897 :     return header()->routing;
     159             :   }
     160             : 
     161             :   void set_routing_id(int32_t new_id) {
     162             :     header()->routing = new_id;
     163             :   }
     164             : 
     165         916 :   int32_t transaction_id() const {
     166         916 :     return header()->txid;
     167             :   }
     168             : 
     169           6 :   void set_transaction_id(int32_t txid) {
     170           6 :     header()->txid = txid;
     171           6 :   }
     172             : 
     173           0 :   uint32_t interrupt_remote_stack_depth_guess() const {
     174           0 :     return header()->interrupt_remote_stack_depth_guess;
     175             :   }
     176             : 
     177           0 :   void set_interrupt_remote_stack_depth_guess(uint32_t depth) {
     178           0 :     DCHECK(is_interrupt());
     179           0 :     header()->interrupt_remote_stack_depth_guess = depth;
     180           0 :   }
     181             : 
     182             :   uint32_t interrupt_local_stack_depth() const {
     183             :     return header()->interrupt_local_stack_depth;
     184             :   }
     185             : 
     186           0 :   void set_interrupt_local_stack_depth(uint32_t depth) {
     187           0 :     DCHECK(is_interrupt());
     188           0 :     header()->interrupt_local_stack_depth = depth;
     189           0 :   }
     190             : 
     191         473 :   int32_t seqno() const {
     192         473 :     return header()->seqno;
     193             :   }
     194             : 
     195           6 :   void set_seqno(int32_t aSeqno) {
     196           6 :     header()->seqno = aSeqno;
     197           6 :   }
     198             : 
     199         982 :   const char* name() const {
     200         982 :     return name_;
     201             :   }
     202             : 
     203             :   void set_name(const char* const aName) {
     204             :     name_ = aName;
     205             :   }
     206             : 
     207         755 :   const mozilla::TimeStamp& create_time() const {
     208         755 :     return create_time_;
     209             :   }
     210             : 
     211             : #if defined(OS_POSIX)
     212             :   uint32_t num_fds() const;
     213             : #endif
     214             : 
     215             :   template<class T>
     216             :   static bool Dispatch(const Message* msg, T* obj, void (T::*func)()) {
     217             :     (obj->*func)();
     218             :     return true;
     219             :   }
     220             : 
     221             :   template<class T>
     222             :   static bool Dispatch(const Message* msg, T* obj, void (T::*func)() const) {
     223             :     (obj->*func)();
     224             :     return true;
     225             :   }
     226             : 
     227             :   template<class T>
     228             :   static bool Dispatch(const Message* msg, T* obj,
     229             :                        void (T::*func)(const Message&)) {
     230             :     (obj->*func)(*msg);
     231             :     return true;
     232             :   }
     233             : 
     234             :   template<class T>
     235             :   static bool Dispatch(const Message* msg, T* obj,
     236             :                        void (T::*func)(const Message&) const) {
     237             :     (obj->*func)(*msg);
     238             :     return true;
     239             :   }
     240             : 
     241             :   // Used for async messages with no parameters.
     242             :   static void Log(const Message* msg, std::wstring* l) {
     243             :   }
     244             : 
     245         388 :   static int HeaderSizeFromData(const char* range_start,
     246             :                                 const char* range_end) {
     247             : #ifdef MOZ_TASK_TRACER
     248             :     return ((static_cast<unsigned int>(range_end - range_start) >= sizeof(Header)) &&
     249             :             (reinterpret_cast<const Header*>(range_start)->flags &
     250             :              TASKTRACER_BIT)) ?
     251             :       sizeof(HeaderTaskTracer) : sizeof(Header);
     252             : #else
     253         388 :     return sizeof(Header);
     254             : #endif
     255             :   }
     256             : 
     257             :   // Figure out how big the message starting at range_start is. Returns 0 if
     258             :   // there's no enough data to determine (i.e., if [range_start, range_end) does
     259             :   // not contain enough of the message header to know the size).
     260         388 :   static uint32_t MessageSize(const char* range_start, const char* range_end) {
     261         388 :     return Pickle::MessageSize(HeaderSizeFromData(range_start, range_end),
     262         388 :                                range_start, range_end);
     263             :   }
     264             : 
     265             : #if defined(OS_POSIX)
     266             :   // On POSIX, a message supports reading / writing FileDescriptor objects.
     267             :   // This is used to pass a file descriptor to the peer of an IPC channel.
     268             : 
     269             :   // Add a descriptor to the end of the set. Returns false iff the set is full.
     270             :   bool WriteFileDescriptor(const base::FileDescriptor& descriptor);
     271             :   // Get a file descriptor from the message. Returns false on error.
     272             :   //   iter: a Pickle iterator to the current location in the message.
     273             :   bool ReadFileDescriptor(PickleIterator* iter, base::FileDescriptor* descriptor) const;
     274             : 
     275             : #if defined(OS_MACOSX)
     276             :   void set_fd_cookie(uint32_t cookie) {
     277             :     header()->cookie = cookie;
     278             :   }
     279             :   uint32_t fd_cookie() const {
     280             :     return header()->cookie;
     281             :   }
     282             : #endif
     283             : #endif
     284             : 
     285             : 
     286             :   friend class Channel;
     287             :   friend class MessageReplyDeserializer;
     288             :   friend class SyncMessage;
     289             : 
     290           6 :   void set_sync() {
     291           6 :     header()->flags |= SYNC_BIT;
     292           6 :   }
     293             : 
     294           0 :   void set_interrupt() {
     295           0 :     header()->flags |= INTERRUPT_BIT;
     296           0 :   }
     297             : 
     298             : #ifdef MOZ_TASK_TRACER
     299             :   void TaskTracerDispatch();
     300             :   class AutoTaskTracerRun
     301             :     : public mozilla::tasktracer::AutoSaveCurTraceInfo {
     302             :     Message& mMsg;
     303             :     uint64_t mTaskId;
     304             :     uint64_t mSourceEventId;
     305             :   public:
     306             :     explicit AutoTaskTracerRun(Message& aMsg);
     307             :     ~AutoTaskTracerRun();
     308             :   };
     309             : #endif
     310             : 
     311             : #if !defined(OS_MACOSX)
     312             :  protected:
     313             : #endif
     314             : 
     315             :   // flags
     316             :   enum {
     317             :     NESTED_MASK     = 0x0003,
     318             :     PRIO_BIT        = 0x0004,
     319             :     SYNC_BIT        = 0x0008,
     320             :     REPLY_BIT       = 0x0010,
     321             :     REPLY_ERROR_BIT = 0x0020,
     322             :     INTERRUPT_BIT   = 0x0040,
     323             :     COMPRESS_BIT    = 0x0080,
     324             :     COMPRESSALL_BIT = 0x0100,
     325             :     CONSTRUCTOR_BIT = 0x0200,
     326             : #ifdef MOZ_TASK_TRACER
     327             :     TASKTRACER_BIT  = 0x0400,
     328             : #endif
     329             :   };
     330             : 
     331             :   struct Header : Pickle::Header {
     332             :     int32_t routing;  // ID of the view that this message is destined for
     333             :     msgid_t type;   // specifies the user-defined message type
     334             :     uint32_t flags;   // specifies control flags for the message
     335             : #if defined(OS_POSIX)
     336             :     uint32_t num_fds; // the number of descriptors included with this message
     337             : # if defined(OS_MACOSX)
     338             :     uint32_t cookie;  // cookie to ACK that the descriptors have been read.
     339             : # endif
     340             : #endif
     341             :     union {
     342             :       // For Interrupt messages, a guess at what the *other* side's stack depth is.
     343             :       uint32_t interrupt_remote_stack_depth_guess;
     344             : 
     345             :       // For RPC and Urgent messages, a transaction ID for message ordering.
     346             :       int32_t txid;
     347             :     };
     348             :     // The actual local stack depth.
     349             :     uint32_t interrupt_local_stack_depth;
     350             :     // Sequence number
     351             :     int32_t seqno;
     352             :   };
     353             : 
     354             : #ifdef MOZ_TASK_TRACER
     355             :   /**
     356             :    * The type is used as headers of Messages only if TaskTracer is
     357             :    * enabled, or type |Header| would be used instead.
     358             :    */
     359             :   struct HeaderTaskTracer : public Header {
     360             :     uint64_t task_id;
     361             :     uint64_t source_event_id;
     362             :     uint64_t parent_task_id;
     363             :     mozilla::tasktracer::SourceEventType source_event_type;
     364             :   };
     365             : #endif
     366             : 
     367             : #ifdef MOZ_TASK_TRACER
     368             :   bool UseTaskTracerHeader() const {
     369             :     return sizeof(HeaderTaskTracer) == (size() - payload_size());
     370             :   }
     371             : 
     372             :   Header* header() {
     373             :     return UseTaskTracerHeader() ?
     374             :       headerT<HeaderTaskTracer>() : headerT<Header>();
     375             :   }
     376             :   const Header* header() const {
     377             :     return UseTaskTracerHeader() ?
     378             :       headerT<HeaderTaskTracer>() : headerT<Header>();
     379             :   }
     380             : #else
     381        4637 :   Header* header() {
     382        4637 :     return headerT<Header>();
     383             :   }
     384       20777 :   const Header* header() const {
     385       20777 :     return headerT<Header>();
     386             :   }
     387             : #endif
     388             : 
     389             :   void InitLoggingVariables(const char* const name="???");
     390             : 
     391             : #if defined(OS_POSIX)
     392             :   // The set of file descriptors associated with this message.
     393             :   RefPtr<FileDescriptorSet> file_descriptor_set_;
     394             : 
     395             :   // Ensure that a FileDescriptorSet is allocated
     396             :   void EnsureFileDescriptorSet();
     397             : 
     398         956 :   FileDescriptorSet* file_descriptor_set() {
     399         956 :     EnsureFileDescriptorSet();
     400         956 :     return file_descriptor_set_.get();
     401             :   }
     402           0 :   const FileDescriptorSet* file_descriptor_set() const {
     403           0 :     return file_descriptor_set_.get();
     404             :   }
     405             : #endif
     406             : 
     407             :   const char* name_;
     408             : 
     409             :   mozilla::TimeStamp create_time_;
     410             : 
     411             : };
     412             : 
     413             : class MessageInfo {
     414             : public:
     415             :     typedef uint32_t msgid_t;
     416             : 
     417           0 :     explicit MessageInfo(const Message& aMsg)
     418           0 :         : mSeqno(aMsg.seqno()), mType(aMsg.type()) {}
     419             : 
     420           0 :     int32_t seqno() const { return mSeqno; }
     421           0 :     msgid_t type() const { return mType; }
     422             : 
     423             : private:
     424             :     int32_t mSeqno;
     425             :     msgid_t mType;
     426             : };
     427             : 
     428             : //------------------------------------------------------------------------------
     429             : 
     430             : }  // namespace IPC
     431             : 
     432             : enum SpecialRoutingIDs {
     433             :   // indicates that we don't have a routing ID yet.
     434             :   MSG_ROUTING_NONE = kint32min,
     435             : 
     436             :   // indicates a general message not sent to a particular tab.
     437             :   MSG_ROUTING_CONTROL = kint32max
     438             : };
     439             : 
     440             : #define IPC_REPLY_ID 0xFFF0  // Special message id for replies
     441             : #define IPC_LOGGING_ID 0xFFF1  // Special message id for logging
     442             : 
     443             : #endif  // CHROME_COMMON_IPC_MESSAGE_H__

Generated by: LCOV version 1.13