summaryrefslogtreecommitdiffstats
path: root/ipc/glue/MessageLink.h
blob: bad3930799cb2bf0cbf64f0ceae2b48a8d5bf99b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 * vim: sw=2 ts=4 et :
 */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef ipc_glue_MessageLink_h
#define ipc_glue_MessageLink_h 1

#include <cstdint>
#include "base/message_loop.h"
#include "mozilla/Assertions.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/ipc/Transport.h"

namespace IPC {
class Message;
}

namespace mozilla {
namespace ipc {

class MessageChannel;

struct HasResultCodes {
  enum Result {
    MsgProcessed,
    MsgDropped,
    MsgNotKnown,
    MsgNotAllowed,
    MsgPayloadError,
    MsgProcessingError,
    MsgRouteError,
    MsgValueError
  };
};

enum Side : uint8_t { ParentSide, ChildSide, UnknownSide };

class MessageLink {
 public:
  typedef IPC::Message Message;

  explicit MessageLink(MessageChannel* aChan);
  virtual ~MessageLink();

  // This is called immediately before the MessageChannel destroys its
  // MessageLink. See the implementation in ThreadLink for details.
  virtual void PrepareToDestroy(){};

  // n.b.: These methods all require that the channel monitor is
  // held when they are invoked.
  virtual void SendMessage(mozilla::UniquePtr<Message> msg) = 0;
  virtual void SendClose() = 0;

  virtual bool Unsound_IsClosed() const = 0;
  virtual uint32_t Unsound_NumQueuedMessages() const = 0;

 protected:
  MessageChannel* mChan;
};

class ProcessLink : public MessageLink, public Transport::Listener {
  void OnCloseChannel();
  void OnChannelOpened();
  void OnTakeConnectedChannel();

  void AssertIOThread() const {
    MOZ_ASSERT(mIOLoop == MessageLoop::current(), "not on I/O thread!");
  }

 public:
  explicit ProcessLink(MessageChannel* chan);
  virtual ~ProcessLink();

  // The ProcessLink will register itself as the IPC::Channel::Listener on the
  // transport passed here. If the transport already has a listener registered
  // then a listener chain will be established (the ProcessLink listener
  // methods will be called first and may call some methods on the original
  // listener as well). Once the channel is closed (either via normal shutdown
  // or a pipe error) the chain will be destroyed and the original listener
  // will again be registered.
  void Open(UniquePtr<Transport> aTransport, MessageLoop* aIOLoop, Side aSide);

  // Run on the I/O thread, only when using inter-process link.
  // These methods acquire the monitor and forward to the
  // similarly named methods in AsyncChannel below
  // (OnMessageReceivedFromLink(), etc)
  virtual void OnMessageReceived(Message&& msg) override;
  virtual void OnChannelConnected(int32_t peer_pid) override;
  virtual void OnChannelError() override;

  virtual void SendMessage(mozilla::UniquePtr<Message> msg) override;
  virtual void SendClose() override;

  virtual bool Unsound_IsClosed() const override;
  virtual uint32_t Unsound_NumQueuedMessages() const override;

 protected:
  void OnChannelConnectError();

 protected:
  UniquePtr<Transport> mTransport;
  MessageLoop* mIOLoop;                    // thread where IO happens
  Transport::Listener* mExistingListener;  // channel's previous listener
};

class ThreadLink : public MessageLink {
 public:
  ThreadLink(MessageChannel* aChan, MessageChannel* aTargetChan);
  virtual ~ThreadLink() = default;

  virtual void PrepareToDestroy() override;

  virtual void SendMessage(mozilla::UniquePtr<Message> msg) override;
  virtual void SendClose() override;

  virtual bool Unsound_IsClosed() const override;
  virtual uint32_t Unsound_NumQueuedMessages() const override;

 protected:
  MessageChannel* mTargetChan;
};

}  // namespace ipc
}  // namespace mozilla

#endif  // ifndef ipc_glue_MessageLink_h