1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/ipc/glue/MessageLink.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,188 @@ 1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- 1.5 + * vim: sw=4 ts=4 et : 1.6 + */ 1.7 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.8 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.9 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.10 + 1.11 +#ifndef ipc_glue_MessageLink_h 1.12 +#define ipc_glue_MessageLink_h 1 1.13 + 1.14 +#include "base/basictypes.h" 1.15 +#include "base/message_loop.h" 1.16 + 1.17 +#include "mozilla/WeakPtr.h" 1.18 +#include "mozilla/ipc/Transport.h" 1.19 + 1.20 +namespace mozilla { 1.21 +namespace ipc { 1.22 + 1.23 +class MessageChannel; 1.24 + 1.25 +struct HasResultCodes 1.26 +{ 1.27 + enum Result { 1.28 + MsgProcessed, 1.29 + MsgDropped, 1.30 + MsgNotKnown, 1.31 + MsgNotAllowed, 1.32 + MsgPayloadError, 1.33 + MsgProcessingError, 1.34 + MsgRouteError, 1.35 + MsgValueError 1.36 + }; 1.37 +}; 1.38 + 1.39 +enum Side { 1.40 + ParentSide, 1.41 + ChildSide, 1.42 + UnknownSide 1.43 +}; 1.44 + 1.45 +enum ChannelState { 1.46 + ChannelClosed, 1.47 + ChannelOpening, 1.48 + ChannelConnected, 1.49 + ChannelTimeout, 1.50 + ChannelClosing, 1.51 + ChannelError 1.52 +}; 1.53 + 1.54 +// What happens if Interrupt calls race? 1.55 +enum RacyInterruptPolicy { 1.56 + RIPError, 1.57 + RIPChildWins, 1.58 + RIPParentWins 1.59 +}; 1.60 + 1.61 +class MessageListener 1.62 + : protected HasResultCodes, 1.63 + public mozilla::SupportsWeakPtr<MessageListener> 1.64 +{ 1.65 + public: 1.66 + MOZ_DECLARE_REFCOUNTED_TYPENAME(MessageListener) 1.67 + typedef IPC::Message Message; 1.68 + 1.69 + virtual ~MessageListener() { } 1.70 + 1.71 + virtual void OnChannelClose() = 0; 1.72 + virtual void OnChannelError() = 0; 1.73 + virtual Result OnMessageReceived(const Message& aMessage) = 0; 1.74 + virtual Result OnMessageReceived(const Message& aMessage, Message *& aReply) = 0; 1.75 + virtual Result OnCallReceived(const Message& aMessage, Message *& aReply) = 0; 1.76 + virtual void OnProcessingError(Result aError) = 0; 1.77 + virtual void OnChannelConnected(int32_t peer_pid) {} 1.78 + virtual bool OnReplyTimeout() { 1.79 + return false; 1.80 + } 1.81 + 1.82 + virtual void OnEnteredCxxStack() { 1.83 + NS_RUNTIMEABORT("default impl shouldn't be invoked"); 1.84 + } 1.85 + virtual void OnExitedCxxStack() { 1.86 + NS_RUNTIMEABORT("default impl shouldn't be invoked"); 1.87 + } 1.88 + virtual void OnEnteredCall() { 1.89 + NS_RUNTIMEABORT("default impl shouldn't be invoked"); 1.90 + } 1.91 + virtual void OnExitedCall() { 1.92 + NS_RUNTIMEABORT("default impl shouldn't be invoked"); 1.93 + } 1.94 + virtual RacyInterruptPolicy MediateInterruptRace(const Message& parent, 1.95 + const Message& child) 1.96 + { 1.97 + return RIPChildWins; 1.98 + } 1.99 + 1.100 + virtual void ProcessRemoteNativeEventsInInterruptCall() { 1.101 + } 1.102 + 1.103 + // FIXME/bug 792652: this doesn't really belong here, but a 1.104 + // large refactoring is needed to put it where it belongs. 1.105 + virtual int32_t GetProtocolTypeId() = 0; 1.106 +}; 1.107 + 1.108 +class MessageLink 1.109 +{ 1.110 + public: 1.111 + typedef IPC::Message Message; 1.112 + 1.113 + MessageLink(MessageChannel *aChan); 1.114 + virtual ~MessageLink(); 1.115 + 1.116 + // n.b.: These methods all require that the channel monitor is 1.117 + // held when they are invoked. 1.118 + virtual void EchoMessage(Message *msg) = 0; 1.119 + virtual void SendMessage(Message *msg) = 0; 1.120 + virtual void SendClose() = 0; 1.121 + 1.122 + virtual bool Unsound_IsClosed() const = 0; 1.123 + virtual uint32_t Unsound_NumQueuedMessages() const = 0; 1.124 + 1.125 + protected: 1.126 + MessageChannel *mChan; 1.127 +}; 1.128 + 1.129 +class ProcessLink 1.130 + : public MessageLink, 1.131 + public Transport::Listener 1.132 +{ 1.133 + void OnCloseChannel(); 1.134 + void OnChannelOpened(); 1.135 + void OnTakeConnectedChannel(); 1.136 + void OnEchoMessage(Message* msg); 1.137 + 1.138 + void AssertIOThread() const 1.139 + { 1.140 + NS_ABORT_IF_FALSE(mIOLoop == MessageLoop::current(), 1.141 + "not on I/O thread!"); 1.142 + } 1.143 + 1.144 + public: 1.145 + ProcessLink(MessageChannel *chan); 1.146 + virtual ~ProcessLink(); 1.147 + void Open(Transport* aTransport, MessageLoop *aIOLoop, Side aSide); 1.148 + 1.149 + // Run on the I/O thread, only when using inter-process link. 1.150 + // These methods acquire the monitor and forward to the 1.151 + // similarly named methods in AsyncChannel below 1.152 + // (OnMessageReceivedFromLink(), etc) 1.153 + virtual void OnMessageReceived(const Message& msg) MOZ_OVERRIDE; 1.154 + virtual void OnChannelConnected(int32_t peer_pid) MOZ_OVERRIDE; 1.155 + virtual void OnChannelError() MOZ_OVERRIDE; 1.156 + 1.157 + virtual void EchoMessage(Message *msg) MOZ_OVERRIDE; 1.158 + virtual void SendMessage(Message *msg) MOZ_OVERRIDE; 1.159 + virtual void SendClose() MOZ_OVERRIDE; 1.160 + 1.161 + virtual bool Unsound_IsClosed() const MOZ_OVERRIDE; 1.162 + virtual uint32_t Unsound_NumQueuedMessages() const MOZ_OVERRIDE; 1.163 + 1.164 + protected: 1.165 + Transport* mTransport; 1.166 + MessageLoop* mIOLoop; // thread where IO happens 1.167 + Transport::Listener* mExistingListener; // channel's previous listener 1.168 +}; 1.169 + 1.170 +class ThreadLink : public MessageLink 1.171 +{ 1.172 + public: 1.173 + ThreadLink(MessageChannel *aChan, MessageChannel *aTargetChan); 1.174 + virtual ~ThreadLink(); 1.175 + 1.176 + virtual void EchoMessage(Message *msg) MOZ_OVERRIDE; 1.177 + virtual void SendMessage(Message *msg) MOZ_OVERRIDE; 1.178 + virtual void SendClose() MOZ_OVERRIDE; 1.179 + 1.180 + virtual bool Unsound_IsClosed() const MOZ_OVERRIDE; 1.181 + virtual uint32_t Unsound_NumQueuedMessages() const MOZ_OVERRIDE; 1.182 + 1.183 + protected: 1.184 + MessageChannel* mTargetChan; 1.185 +}; 1.186 + 1.187 +} // namespace ipc 1.188 +} // namespace mozilla 1.189 + 1.190 +#endif // ifndef ipc_glue_MessageLink_h 1.191 +