LCOV - code coverage report
Current view: directory - objdir/dist/include/mozilla/ipc - AsyncChannel.h (source / functions) Found Hit Coverage
Test: app.info Lines: 23 3 13.0 %
Date: 2012-06-02 Functions: 14 3 21.4 %

       1                 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2                 :  * vim: sw=4 ts=4 et :
       3                 :  */
       4                 : /* ***** BEGIN LICENSE BLOCK *****
       5                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       6                 :  *
       7                 :  * The contents of this file are subject to the Mozilla Public License Version
       8                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       9                 :  * the License. You may obtain a copy of the License at
      10                 :  * http://www.mozilla.org/MPL/
      11                 :  *
      12                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      13                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      14                 :  * for the specific language governing rights and limitations under the
      15                 :  * License.
      16                 :  *
      17                 :  * The Original Code is Mozilla Plugin App.
      18                 :  *
      19                 :  * The Initial Developer of the Original Code is
      20                 :  *   Chris Jones <jones.chris.g@gmail.com>
      21                 :  * Portions created by the Initial Developer are Copyright (C) 2009
      22                 :  * the Initial Developer. All Rights Reserved.
      23                 :  *
      24                 :  * Contributor(s):
      25                 :  *
      26                 :  * Alternatively, the contents of this file may be used under the terms of
      27                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      28                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      29                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      30                 :  * of those above. If you wish to allow use of your version of this file only
      31                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      32                 :  * use your version of this file under the terms of the MPL, indicate your
      33                 :  * decision by deleting the provisions above and replace them with the notice
      34                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      35                 :  * the provisions above, a recipient may use your version of this file under
      36                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      37                 :  *
      38                 :  * ***** END LICENSE BLOCK ***** */
      39                 : 
      40                 : #ifndef ipc_glue_AsyncChannel_h
      41                 : #define ipc_glue_AsyncChannel_h 1
      42                 : 
      43                 : #include "base/basictypes.h"
      44                 : #include "base/message_loop.h"
      45                 : 
      46                 : #include "mozilla/Monitor.h"
      47                 : #include "mozilla/ipc/Transport.h"
      48                 : 
      49                 : //-----------------------------------------------------------------------------
      50                 : 
      51                 : namespace mozilla {
      52                 : namespace ipc {
      53                 : 
      54                 : struct HasResultCodes
      55               3 : {
      56                 :     enum Result {
      57                 :         MsgProcessed,
      58                 :         MsgDropped,
      59                 :         MsgNotKnown,
      60                 :         MsgNotAllowed,
      61                 :         MsgPayloadError,
      62                 :         MsgProcessingError,
      63                 :         MsgRouteError,
      64                 :         MsgValueError
      65                 :     };
      66                 : };
      67                 : 
      68                 : 
      69                 : class RefCountedMonitor : public Monitor
      70               0 : {
      71                 : public:
      72               0 :     RefCountedMonitor() 
      73               0 :         : Monitor("mozilla.ipc.AsyncChannel.mMonitor")
      74               0 :     {}
      75                 : 
      76               0 :     NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RefCountedMonitor)
      77                 : };
      78                 : 
      79                 : class AsyncChannel : protected HasResultCodes
      80                 : {
      81                 : protected:
      82                 :     typedef mozilla::Monitor Monitor;
      83                 : 
      84                 :     enum ChannelState {
      85                 :         ChannelClosed,
      86                 :         ChannelOpening,
      87                 :         ChannelConnected,
      88                 :         ChannelTimeout,
      89                 :         ChannelClosing,
      90                 :         ChannelError
      91                 :     };
      92                 : 
      93                 : public:
      94                 :     typedef IPC::Message Message;
      95                 :     typedef mozilla::ipc::Transport Transport;
      96                 : 
      97                 :     class /*NS_INTERFACE_CLASS*/ AsyncListener: protected HasResultCodes
      98               2 :     {
      99                 :     public:
     100               2 :         virtual ~AsyncListener() { }
     101                 : 
     102                 :         virtual void OnChannelClose() = 0;
     103                 :         virtual void OnChannelError() = 0;
     104                 :         virtual Result OnMessageReceived(const Message& aMessage) = 0;
     105                 :         virtual void OnProcessingError(Result aError) = 0;
     106               0 :         virtual void OnChannelConnected(int32 peer_pid) {};
     107                 :     };
     108                 : 
     109                 :     enum Side { Parent, Child, Unknown };
     110                 : 
     111                 : public:
     112                 :     //
     113                 :     // These methods are called on the "worker" thread
     114                 :     //
     115                 :     AsyncChannel(AsyncListener* aListener);
     116                 :     virtual ~AsyncChannel();
     117                 : 
     118                 :     // "Open" from the perspective of the transport layer; the underlying
     119                 :     // socketpair/pipe should already be created.
     120                 :     //
     121                 :     // Returns true iff the transport layer was successfully connected,
     122                 :     // i.e., mChannelState == ChannelConnected.
     123                 :     bool Open(Transport* aTransport, MessageLoop* aIOLoop=0, Side aSide=Unknown);
     124                 :     
     125                 :     // "Open" a connection to another thread in the same process.
     126                 :     //
     127                 :     // Returns true iff the transport layer was successfully connected,
     128                 :     // i.e., mChannelState == ChannelConnected.
     129                 :     //
     130                 :     // For more details on the process of opening a channel between
     131                 :     // threads, see the extended comment on this function
     132                 :     // in AsyncChannel.cpp.
     133                 :     bool Open(AsyncChannel *aTargetChan, MessageLoop *aTargetLoop, Side aSide);
     134                 : 
     135                 :     // Close the underlying transport channel.
     136                 :     void Close();
     137                 : 
     138                 :     // Asynchronously send a message to the other side of the channel
     139                 :     virtual bool Send(Message* msg);
     140                 : 
     141                 :     // Asynchronously deliver a message back to this side of the
     142                 :     // channel
     143                 :     virtual bool Echo(Message* msg);
     144                 : 
     145                 :     // Send OnChannelConnected notification to listeners.
     146                 :     void DispatchOnChannelConnected(int32 peer_pid);
     147                 : 
     148                 :     //
     149                 :     // Each AsyncChannel is associated with either a ProcessLink or a
     150                 :     // ThreadLink via the field mLink.  The type of link is determined
     151                 :     // by whether this AsyncChannel is communicating with another
     152                 :     // process or another thread.  In the former case, file
     153                 :     // descriptors or a socket are used via the I/O queue.  In the
     154                 :     // latter case, messages are enqueued directly onto the target
     155                 :     // thread's work queue.
     156                 :     //
     157                 : 
     158                 :     class Link {
     159                 :     protected:
     160                 :         AsyncChannel *mChan;
     161                 : 
     162                 :     public:
     163                 :         Link(AsyncChannel *aChan);
     164                 :         virtual ~Link();
     165                 : 
     166                 :         // n.b.: These methods all require that the channel monitor is
     167                 :         // held when they are invoked.
     168                 :         virtual void EchoMessage(Message *msg) = 0;
     169                 :         virtual void SendMessage(Message *msg) = 0;
     170                 :         virtual void SendClose() = 0;
     171                 :     };
     172                 : 
     173                 :     class ProcessLink : public Link, public Transport::Listener {
     174                 :     protected:
     175                 :         Transport* mTransport;
     176                 :         MessageLoop* mIOLoop;       // thread where IO happens
     177                 :         Transport::Listener* mExistingListener; // channel's previous listener
     178                 :     
     179                 :         void OnCloseChannel();
     180                 :         void OnChannelOpened();
     181                 :         void OnEchoMessage(Message* msg);
     182                 : 
     183               0 :         void AssertIOThread() const
     184                 :         {
     185               0 :             NS_ABORT_IF_FALSE(mIOLoop == MessageLoop::current(),
     186                 :                               "not on I/O thread!");
     187               0 :         }
     188                 : 
     189                 :     public:
     190                 :         ProcessLink(AsyncChannel *chan);
     191                 :         virtual ~ProcessLink();
     192                 :         void Open(Transport* aTransport, MessageLoop *aIOLoop, Side aSide);
     193                 :         
     194                 :         // Run on the I/O thread, only when using inter-process link.
     195                 :         // These methods acquire the monitor and forward to the
     196                 :         // similarly named methods in AsyncChannel below
     197                 :         // (OnMessageReceivedFromLink(), etc)
     198                 :         NS_OVERRIDE virtual void OnMessageReceived(const Message& msg);
     199                 :         NS_OVERRIDE virtual void OnChannelConnected(int32 peer_pid);
     200                 :         NS_OVERRIDE virtual void OnChannelError();
     201                 : 
     202                 :         NS_OVERRIDE virtual void EchoMessage(Message *msg);
     203                 :         NS_OVERRIDE virtual void SendMessage(Message *msg);
     204                 :         NS_OVERRIDE virtual void SendClose();
     205                 :     };
     206                 :     
     207                 :     class ThreadLink : public Link {
     208                 :     protected:
     209                 :         AsyncChannel* mTargetChan;
     210                 :     
     211                 :     public:
     212                 :         ThreadLink(AsyncChannel *aChan, AsyncChannel *aTargetChan);
     213                 :         virtual ~ThreadLink();
     214                 : 
     215                 :         NS_OVERRIDE virtual void EchoMessage(Message *msg);
     216                 :         NS_OVERRIDE virtual void SendMessage(Message *msg);
     217                 :         NS_OVERRIDE virtual void SendClose();
     218                 :     };
     219                 : 
     220                 : protected:
     221                 :     // The "link" thread is either the I/O thread (ProcessLink) or the
     222                 :     // other actor's work thread (ThreadLink).  In either case, it is
     223                 :     // NOT our worker thread.
     224               0 :     void AssertLinkThread() const
     225                 :     {
     226               0 :         NS_ABORT_IF_FALSE(mWorkerLoop != MessageLoop::current(),
     227                 :                           "on worker thread but should not be!");
     228               0 :     }
     229                 : 
     230                 :     // Can be run on either thread
     231               0 :     void AssertWorkerThread() const
     232                 :     {
     233               0 :         NS_ABORT_IF_FALSE(mWorkerLoop == MessageLoop::current(),
     234                 :                           "not on worker thread!");
     235               0 :     }
     236                 : 
     237               0 :     bool Connected() const {
     238               0 :         mMonitor->AssertCurrentThreadOwns();
     239               0 :         return ChannelConnected == mChannelState;
     240                 :     }
     241                 : 
     242                 :     // Return true if |msg| is a special message targeted at the IO
     243                 :     // thread, in which case it shouldn't be delivered to the worker.
     244                 :     virtual bool MaybeInterceptSpecialIOMessage(const Message& msg);
     245                 :     void ProcessGoodbyeMessage();
     246                 : 
     247                 :     // Runs on the link thread. Invoked either from the I/O thread methods above
     248                 :     // or directly from the other actor if using a thread-based link.
     249                 :     // 
     250                 :     // n.b.: mMonitor is always held when these methods are invoked.
     251                 :     // In the case of a ProcessLink, it is acquired by the ProcessLink.
     252                 :     // In the case of a ThreadLink, it is acquired by the other actor, 
     253                 :     // which then invokes these methods directly.
     254                 :     virtual void OnMessageReceivedFromLink(const Message& msg);
     255                 :     virtual void OnChannelErrorFromLink();
     256                 :     void PostErrorNotifyTask();
     257                 : 
     258                 :     // Run on the worker thread
     259                 :     void OnDispatchMessage(const Message& aMsg);
     260                 :     virtual bool OnSpecialMessage(uint16 id, const Message& msg);
     261                 :     void SendSpecialMessage(Message* msg) const;
     262                 : 
     263                 :     // Tell the IO thread to close the channel and wait for it to ACK.
     264                 :     void SynchronouslyClose();
     265                 : 
     266                 :     bool MaybeHandleError(Result code, const char* channelName);
     267                 :     void ReportConnectionError(const char* channelName) const;
     268                 : 
     269                 :     // Run on the worker thread
     270                 : 
     271                 :     void OnNotifyMaybeChannelError();
     272               0 :     virtual bool ShouldDeferNotifyMaybeError() const {
     273               0 :         return false;
     274                 :     }
     275                 :     void NotifyChannelClosed();
     276                 :     void NotifyMaybeChannelError();
     277                 :     void OnOpenAsSlave(AsyncChannel *aTargetChan, Side aSide);
     278                 :     void CommonThreadOpenInit(AsyncChannel *aTargetChan, Side aSide);
     279                 : 
     280                 :     virtual void Clear();
     281                 : 
     282                 :     AsyncListener* mListener;
     283                 :     ChannelState mChannelState;
     284                 :     nsRefPtr<RefCountedMonitor> mMonitor;
     285                 :     MessageLoop* mWorkerLoop;   // thread where work is done
     286                 :     bool mChild;                // am I the child or parent?
     287                 :     CancelableTask* mChannelErrorTask; // NotifyMaybeChannelError runnable
     288                 :     Link *mLink;                // link to other thread/process
     289                 : };
     290                 : 
     291                 : } // namespace ipc
     292                 : } // namespace mozilla
     293                 : #endif  // ifndef ipc_glue_AsyncChannel_h

Generated by: LCOV version 1.7