1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2  * vim: sw=2 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/. */
7 
8 #ifndef ipc_glue_MessageLink_h
9 #define ipc_glue_MessageLink_h 1
10 
11 #include "base/basictypes.h"
12 #include "base/message_loop.h"
13 
14 #include "mozilla/WeakPtr.h"
15 #include "mozilla/UniquePtr.h"
16 #include "mozilla/ipc/Transport.h"
17 
18 namespace mozilla {
19 namespace ipc {
20 
21 class MessageChannel;
22 
23 struct HasResultCodes {
24   enum Result {
25     MsgProcessed,
26     MsgDropped,
27     MsgNotKnown,
28     MsgNotAllowed,
29     MsgPayloadError,
30     MsgProcessingError,
31     MsgRouteError,
32     MsgValueError
33   };
34 };
35 
36 enum Side : uint8_t { ParentSide, ChildSide, UnknownSide };
37 
38 class MessageLink {
39  public:
40   typedef IPC::Message Message;
41 
42   explicit MessageLink(MessageChannel* aChan);
43   virtual ~MessageLink();
44 
45   // n.b.: These methods all require that the channel monitor is
46   // held when they are invoked.
47   virtual void EchoMessage(Message* msg) = 0;
48   virtual void SendMessage(Message* msg) = 0;
49   virtual void SendClose() = 0;
50 
51   virtual bool Unsound_IsClosed() const = 0;
52   virtual uint32_t Unsound_NumQueuedMessages() const = 0;
53 
54  protected:
55   MessageChannel* mChan;
56 };
57 
58 class ProcessLink : public MessageLink, public Transport::Listener {
59   void OnCloseChannel();
60   void OnChannelOpened();
61   void OnTakeConnectedChannel();
62   void OnEchoMessage(Message* msg);
63 
AssertIOThread()64   void AssertIOThread() const {
65     MOZ_ASSERT(mIOLoop == MessageLoop::current(), "not on I/O thread!");
66   }
67 
68  public:
69   explicit ProcessLink(MessageChannel* chan);
70   virtual ~ProcessLink();
71 
72   // The ProcessLink will register itself as the IPC::Channel::Listener on the
73   // transport passed here. If the transport already has a listener registered
74   // then a listener chain will be established (the ProcessLink listener
75   // methods will be called first and may call some methods on the original
76   // listener as well). Once the channel is closed (either via normal shutdown
77   // or a pipe error) the chain will be destroyed and the original listener
78   // will again be registered.
79   void Open(UniquePtr<Transport> aTransport, MessageLoop* aIOLoop, Side aSide);
80 
81   // Run on the I/O thread, only when using inter-process link.
82   // These methods acquire the monitor and forward to the
83   // similarly named methods in AsyncChannel below
84   // (OnMessageReceivedFromLink(), etc)
85   virtual void OnMessageReceived(Message&& msg) override;
86   virtual void OnChannelConnected(int32_t peer_pid) override;
87   virtual void OnChannelError() override;
88 
89   virtual void EchoMessage(Message* msg) override;
90   virtual void SendMessage(Message* msg) override;
91   virtual void SendClose() override;
92 
93   virtual bool Unsound_IsClosed() const override;
94   virtual uint32_t Unsound_NumQueuedMessages() const override;
95 
96  protected:
97   void OnChannelConnectError();
98 
99  protected:
100   UniquePtr<Transport> mTransport;
101   MessageLoop* mIOLoop;                    // thread where IO happens
102   Transport::Listener* mExistingListener;  // channel's previous listener
103 };
104 
105 class ThreadLink : public MessageLink {
106  public:
107   ThreadLink(MessageChannel* aChan, MessageChannel* aTargetChan);
108   virtual ~ThreadLink();
109 
110   virtual void EchoMessage(Message* msg) override;
111   virtual void SendMessage(Message* msg) override;
112   virtual void SendClose() override;
113 
114   virtual bool Unsound_IsClosed() const override;
115   virtual uint32_t Unsound_NumQueuedMessages() const override;
116 
117  protected:
118   MessageChannel* mTargetChan;
119 };
120 
121 }  // namespace ipc
122 }  // namespace mozilla
123 
124 #endif  // ifndef ipc_glue_MessageLink_h
125