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