ipc/glue/ProtocolUtils.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     2  * vim: sw=4 ts=4 et :
     3  */
     4 /* This Source Code Form is subject to the terms of the Mozilla Public
     5  * License, v. 2.0. If a copy of the MPL was not distributed with this
     6  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     8 #ifndef mozilla_ipc_ProtocolUtils_h
     9 #define mozilla_ipc_ProtocolUtils_h 1
    11 #include "base/process.h"
    12 #include "base/process_util.h"
    13 #include "chrome/common/ipc_message_utils.h"
    15 #include "prenv.h"
    17 #include "IPCMessageStart.h"
    18 #include "mozilla/Attributes.h"
    19 #include "mozilla/ipc/FileDescriptor.h"
    20 #include "mozilla/ipc/Shmem.h"
    21 #include "mozilla/ipc/Transport.h"
    22 #include "mozilla/ipc/MessageLink.h"
    23 #include "mozilla/LinkedList.h"
    25 #if defined(ANDROID) && defined(DEBUG)
    26 #include <android/log.h>
    27 #endif
    29 // WARNING: this takes into account the private, special-message-type
    30 // enum in ipc_channel.h.  They need to be kept in sync.
    31 namespace {
    32 // XXX the max message ID is actually kuint32max now ... when this
    33 // changed, the assumptions of the special message IDs changed in that
    34 // they're not carving out messages from likely-unallocated space, but
    35 // rather carving out messages from the end of space allocated to
    36 // protocol 0.  Oops!  We can get away with this until protocol 0
    37 // starts approaching its 65,536th message.
    38 enum {
    39     CHANNEL_OPENED_MESSAGE_TYPE = kuint16max - 5,
    40     SHMEM_DESTROYED_MESSAGE_TYPE = kuint16max - 4,
    41     SHMEM_CREATED_MESSAGE_TYPE = kuint16max - 3,
    42     GOODBYE_MESSAGE_TYPE       = kuint16max - 2
    44     // kuint16max - 1 is used by ipc_channel.h.
    45 };
    46 }
    48 namespace mozilla {
    49 namespace dom {
    50 class ContentParent;
    51 }
    53 namespace net {
    54 class NeckoParent;
    55 }
    57 namespace ipc {
    59 #ifdef XP_WIN
    60 const base::ProcessHandle kInvalidProcessHandle = INVALID_HANDLE_VALUE;
    61 #else
    62 const base::ProcessHandle kInvalidProcessHandle = -1;
    63 #endif
    65 class ProtocolFdMapping;
    66 class ProtocolCloneContext;
    68 // Used to pass references to protocol actors across the wire.
    69 // Actors created on the parent-side have a positive ID, and actors
    70 // allocated on the child side have a negative ID.
    71 struct ActorHandle
    72 {
    73     int mId;
    74 };
    76 // Used internally to represent a "trigger" that might cause a state
    77 // transition.  Triggers are normalized across parent+child to Send
    78 // and Recv (instead of child-in, child-out, parent-in, parent-out) so
    79 // that they can share the same state machine implementation.  To
    80 // further normalize, |Send| is used for 'call', |Recv| for 'answer'.
    81 struct Trigger
    82 {
    83     enum Action { Send, Recv };
    85     Trigger(Action action, int32_t msg) :
    86         mAction(action),
    87         mMsg(msg)
    88     {}
    90     Action mAction;
    91     int32_t mMsg;
    92 };
    94 class ProtocolCloneContext
    95 {
    96   typedef mozilla::dom::ContentParent ContentParent;
    97   typedef mozilla::net::NeckoParent NeckoParent;
    99   ContentParent* mContentParent;
   100   NeckoParent* mNeckoParent;
   102 public:
   103   ProtocolCloneContext()
   104     : mContentParent(nullptr)
   105     , mNeckoParent(nullptr)
   106   {}
   108   void SetContentParent(ContentParent* aContentParent)
   109   {
   110     mContentParent = aContentParent;
   111   }
   113   ContentParent* GetContentParent() { return mContentParent; }
   115   void SetNeckoParent(NeckoParent* aNeckoParent)
   116   {
   117     mNeckoParent = aNeckoParent;
   118   }
   120   NeckoParent* GetNeckoParent() { return mNeckoParent; }
   121 };
   123 template<class ListenerT>
   124 class /*NS_INTERFACE_CLASS*/ IProtocolManager
   125 {
   126 public:
   127     enum ActorDestroyReason {
   128         FailedConstructor,
   129         Deletion,
   130         AncestorDeletion,
   131         NormalShutdown,
   132         AbnormalShutdown
   133     };
   135     typedef base::ProcessHandle ProcessHandle;
   137     virtual int32_t Register(ListenerT*) = 0;
   138     virtual int32_t RegisterID(ListenerT*, int32_t) = 0;
   139     virtual ListenerT* Lookup(int32_t) = 0;
   140     virtual void Unregister(int32_t) = 0;
   141     virtual void RemoveManagee(int32_t, ListenerT*) = 0;
   143     virtual Shmem::SharedMemory* CreateSharedMemory(
   144         size_t, SharedMemory::SharedMemoryType, bool, int32_t*) = 0;
   145     virtual bool AdoptSharedMemory(Shmem::SharedMemory*, int32_t*) = 0;
   146     virtual Shmem::SharedMemory* LookupSharedMemory(int32_t) = 0;
   147     virtual bool IsTrackingSharedMemory(Shmem::SharedMemory*) = 0;
   148     virtual bool DestroySharedMemory(Shmem&) = 0;
   150     // XXX odd ducks, acknowledged
   151     virtual ProcessHandle OtherProcess() const = 0;
   152     virtual MessageChannel* GetIPCChannel() = 0;
   154     // The implementation of function is generated by code generator.
   155     virtual void CloneManagees(ListenerT* aSource,
   156                                ProtocolCloneContext* aCtx) = 0;
   157 };
   159 typedef IPCMessageStart ProtocolId;
   161 /**
   162  * All RPC protocols should implement this interface.
   163  */
   164 class IProtocol : protected MessageListener
   165 {
   166 public:
   167     /**
   168      * This function is used to clone this protocol actor.
   169      *
   170      * see IProtocol::CloneProtocol()
   171      */
   172     virtual IProtocol*
   173     CloneProtocol(MessageChannel* aChannel,
   174                   ProtocolCloneContext* aCtx) = 0;
   175 };
   177 /**
   178  * All top-level protocols should inherit this class.
   179  *
   180  * IToplevelProtocol tracks all top-level protocol actors created from
   181  * this protocol actor.
   182  */
   183 class IToplevelProtocol : public LinkedListElement<IToplevelProtocol>
   184 {
   185 protected:
   186     IToplevelProtocol(ProtocolId aProtoId)
   187         : mProtocolId(aProtoId)
   188         , mTrans(nullptr)
   189     {
   190     }
   192     ~IToplevelProtocol();
   194     /**
   195      * Add an actor to the list of actors that have been opened by this
   196      * protocol.
   197      */
   198     void AddOpenedActor(IToplevelProtocol* aActor);
   200 public:
   201     void SetTransport(Transport* aTrans)
   202     {
   203         mTrans = aTrans;
   204     }
   206     Transport* GetTransport() const { return mTrans; }
   208     ProtocolId GetProtocolId() const { return mProtocolId; }
   210     /**
   211      * Return first of actors of top level protocols opened by this one.
   212      */
   213     IToplevelProtocol* GetFirstOpenedActors()
   214     {
   215         return mOpenActors.getFirst();
   216     }
   217     const IToplevelProtocol* GetFirstOpenedActors() const
   218     {
   219         return mOpenActors.getFirst();
   220     }
   222     virtual IToplevelProtocol*
   223     CloneToplevel(const InfallibleTArray<ProtocolFdMapping>& aFds,
   224                   base::ProcessHandle aPeerProcess,
   225                   ProtocolCloneContext* aCtx);
   227     void CloneOpenedToplevels(IToplevelProtocol* aTemplate,
   228                               const InfallibleTArray<ProtocolFdMapping>& aFds,
   229                               base::ProcessHandle aPeerProcess,
   230                               ProtocolCloneContext* aCtx);
   232 private:
   233     LinkedList<IToplevelProtocol> mOpenActors; // All protocol actors opened by this.
   235     ProtocolId mProtocolId;
   236     Transport* mTrans;
   237 };
   240 inline bool
   241 LoggingEnabled()
   242 {
   243 #if defined(DEBUG)
   244     return !!PR_GetEnv("MOZ_IPC_MESSAGE_LOG");
   245 #else
   246     return false;
   247 #endif
   248 }
   250 MOZ_NEVER_INLINE void
   251 ProtocolErrorBreakpoint(const char* aMsg);
   253 MOZ_NEVER_INLINE void
   254 FatalError(const char* aProtocolName, const char* aMsg,
   255            base::ProcessHandle aHandle, bool aIsParent);
   257 struct PrivateIPDLInterface {};
   259 bool
   260 Bridge(const PrivateIPDLInterface&,
   261        MessageChannel*, base::ProcessHandle, MessageChannel*, base::ProcessHandle,
   262        ProtocolId, ProtocolId);
   264 bool
   265 Open(const PrivateIPDLInterface&,
   266      MessageChannel*, base::ProcessHandle, Transport::Mode,
   267      ProtocolId, ProtocolId);
   269 bool
   270 UnpackChannelOpened(const PrivateIPDLInterface&,
   271                     const IPC::Message&,
   272                     TransportDescriptor*, base::ProcessId*, ProtocolId*);
   274 } // namespace ipc
   275 } // namespace mozilla
   278 namespace IPC {
   280 template <>
   281 struct ParamTraits<mozilla::ipc::ActorHandle>
   282 {
   283     typedef mozilla::ipc::ActorHandle paramType;
   285     static void Write(Message* aMsg, const paramType& aParam)
   286     {
   287         IPC::WriteParam(aMsg, aParam.mId);
   288     }
   290     static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
   291     {
   292         int id;
   293         if (IPC::ReadParam(aMsg, aIter, &id)) {
   294             aResult->mId = id;
   295             return true;
   296         }
   297         return false;
   298     }
   300     static void Log(const paramType& aParam, std::wstring* aLog)
   301     {
   302         aLog->append(StringPrintf(L"(%d)", aParam.mId));
   303     }
   304 };
   306 } // namespace IPC
   309 #endif  // mozilla_ipc_ProtocolUtils_h

mercurial