michael@0: /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- michael@0: * vim: sw=4 ts=4 et : michael@0: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef ipc_glue_MessageLink_h michael@0: #define ipc_glue_MessageLink_h 1 michael@0: michael@0: #include "base/basictypes.h" michael@0: #include "base/message_loop.h" michael@0: michael@0: #include "mozilla/WeakPtr.h" michael@0: #include "mozilla/ipc/Transport.h" michael@0: michael@0: namespace mozilla { michael@0: namespace ipc { michael@0: michael@0: class MessageChannel; michael@0: michael@0: struct HasResultCodes michael@0: { michael@0: enum Result { michael@0: MsgProcessed, michael@0: MsgDropped, michael@0: MsgNotKnown, michael@0: MsgNotAllowed, michael@0: MsgPayloadError, michael@0: MsgProcessingError, michael@0: MsgRouteError, michael@0: MsgValueError michael@0: }; michael@0: }; michael@0: michael@0: enum Side { michael@0: ParentSide, michael@0: ChildSide, michael@0: UnknownSide michael@0: }; michael@0: michael@0: enum ChannelState { michael@0: ChannelClosed, michael@0: ChannelOpening, michael@0: ChannelConnected, michael@0: ChannelTimeout, michael@0: ChannelClosing, michael@0: ChannelError michael@0: }; michael@0: michael@0: // What happens if Interrupt calls race? michael@0: enum RacyInterruptPolicy { michael@0: RIPError, michael@0: RIPChildWins, michael@0: RIPParentWins michael@0: }; michael@0: michael@0: class MessageListener michael@0: : protected HasResultCodes, michael@0: public mozilla::SupportsWeakPtr michael@0: { michael@0: public: michael@0: MOZ_DECLARE_REFCOUNTED_TYPENAME(MessageListener) michael@0: typedef IPC::Message Message; michael@0: michael@0: virtual ~MessageListener() { } michael@0: michael@0: virtual void OnChannelClose() = 0; michael@0: virtual void OnChannelError() = 0; michael@0: virtual Result OnMessageReceived(const Message& aMessage) = 0; michael@0: virtual Result OnMessageReceived(const Message& aMessage, Message *& aReply) = 0; michael@0: virtual Result OnCallReceived(const Message& aMessage, Message *& aReply) = 0; michael@0: virtual void OnProcessingError(Result aError) = 0; michael@0: virtual void OnChannelConnected(int32_t peer_pid) {} michael@0: virtual bool OnReplyTimeout() { michael@0: return false; michael@0: } michael@0: michael@0: virtual void OnEnteredCxxStack() { michael@0: NS_RUNTIMEABORT("default impl shouldn't be invoked"); michael@0: } michael@0: virtual void OnExitedCxxStack() { michael@0: NS_RUNTIMEABORT("default impl shouldn't be invoked"); michael@0: } michael@0: virtual void OnEnteredCall() { michael@0: NS_RUNTIMEABORT("default impl shouldn't be invoked"); michael@0: } michael@0: virtual void OnExitedCall() { michael@0: NS_RUNTIMEABORT("default impl shouldn't be invoked"); michael@0: } michael@0: virtual RacyInterruptPolicy MediateInterruptRace(const Message& parent, michael@0: const Message& child) michael@0: { michael@0: return RIPChildWins; michael@0: } michael@0: michael@0: virtual void ProcessRemoteNativeEventsInInterruptCall() { michael@0: } michael@0: michael@0: // FIXME/bug 792652: this doesn't really belong here, but a michael@0: // large refactoring is needed to put it where it belongs. michael@0: virtual int32_t GetProtocolTypeId() = 0; michael@0: }; michael@0: michael@0: class MessageLink michael@0: { michael@0: public: michael@0: typedef IPC::Message Message; michael@0: michael@0: MessageLink(MessageChannel *aChan); michael@0: virtual ~MessageLink(); michael@0: michael@0: // n.b.: These methods all require that the channel monitor is michael@0: // held when they are invoked. michael@0: virtual void EchoMessage(Message *msg) = 0; michael@0: virtual void SendMessage(Message *msg) = 0; michael@0: virtual void SendClose() = 0; michael@0: michael@0: virtual bool Unsound_IsClosed() const = 0; michael@0: virtual uint32_t Unsound_NumQueuedMessages() const = 0; michael@0: michael@0: protected: michael@0: MessageChannel *mChan; michael@0: }; michael@0: michael@0: class ProcessLink michael@0: : public MessageLink, michael@0: public Transport::Listener michael@0: { michael@0: void OnCloseChannel(); michael@0: void OnChannelOpened(); michael@0: void OnTakeConnectedChannel(); michael@0: void OnEchoMessage(Message* msg); michael@0: michael@0: void AssertIOThread() const michael@0: { michael@0: NS_ABORT_IF_FALSE(mIOLoop == MessageLoop::current(), michael@0: "not on I/O thread!"); michael@0: } michael@0: michael@0: public: michael@0: ProcessLink(MessageChannel *chan); michael@0: virtual ~ProcessLink(); michael@0: void Open(Transport* aTransport, MessageLoop *aIOLoop, Side aSide); michael@0: michael@0: // Run on the I/O thread, only when using inter-process link. michael@0: // These methods acquire the monitor and forward to the michael@0: // similarly named methods in AsyncChannel below michael@0: // (OnMessageReceivedFromLink(), etc) michael@0: virtual void OnMessageReceived(const Message& msg) MOZ_OVERRIDE; michael@0: virtual void OnChannelConnected(int32_t peer_pid) MOZ_OVERRIDE; michael@0: virtual void OnChannelError() MOZ_OVERRIDE; michael@0: michael@0: virtual void EchoMessage(Message *msg) MOZ_OVERRIDE; michael@0: virtual void SendMessage(Message *msg) MOZ_OVERRIDE; michael@0: virtual void SendClose() MOZ_OVERRIDE; michael@0: michael@0: virtual bool Unsound_IsClosed() const MOZ_OVERRIDE; michael@0: virtual uint32_t Unsound_NumQueuedMessages() const MOZ_OVERRIDE; michael@0: michael@0: protected: michael@0: Transport* mTransport; michael@0: MessageLoop* mIOLoop; // thread where IO happens michael@0: Transport::Listener* mExistingListener; // channel's previous listener michael@0: }; michael@0: michael@0: class ThreadLink : public MessageLink michael@0: { michael@0: public: michael@0: ThreadLink(MessageChannel *aChan, MessageChannel *aTargetChan); michael@0: virtual ~ThreadLink(); michael@0: michael@0: virtual void EchoMessage(Message *msg) MOZ_OVERRIDE; michael@0: virtual void SendMessage(Message *msg) MOZ_OVERRIDE; michael@0: virtual void SendClose() MOZ_OVERRIDE; michael@0: michael@0: virtual bool Unsound_IsClosed() const MOZ_OVERRIDE; michael@0: virtual uint32_t Unsound_NumQueuedMessages() const MOZ_OVERRIDE; michael@0: michael@0: protected: michael@0: MessageChannel* mTargetChan; michael@0: }; michael@0: michael@0: } // namespace ipc michael@0: } // namespace mozilla michael@0: michael@0: #endif // ifndef ipc_glue_MessageLink_h michael@0: