LCOV - code coverage report
Current view: top level - media/mtransport - transportflow.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 14 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 4 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
       5             :  * You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : // Original author: ekr@rtfm.com
       8             : 
       9             : #ifndef transportflow_h__
      10             : #define transportflow_h__
      11             : 
      12             : #include <deque>
      13             : #include <queue>
      14             : #include <string>
      15             : 
      16             : #include "nscore.h"
      17             : #include "nsISupportsImpl.h"
      18             : #include "mozilla/UniquePtr.h"
      19             : #include "transportlayer.h"
      20             : #include "m_cpp_utils.h"
      21             : #include "nsAutoPtr.h"
      22             : 
      23             : // A stack of transport layers acts as a flow.
      24             : // Generally, one reads and writes to the top layer.
      25             : 
      26             : // This code has a confusing hybrid threading model which
      27             : // probably needs some eventual refactoring.
      28             : // TODO(ekr@rtfm.com): Bug 844891
      29             : //
      30             : // TransportFlows are not inherently bound to a thread *but*
      31             : // TransportLayers can be. If any layer in a flow is bound
      32             : // to a given thread, then all layers in the flow MUST be
      33             : // bound to that thread and you can only manipulate the
      34             : // flow (push layers, write, etc.) on that thread.
      35             : //
      36             : // The sole official exception to this is that you are
      37             : // allowed to *destroy* a flow off the bound thread provided
      38             : // that there are no listeners on its signals. This exception
      39             : // is designed to allow idioms where you create the flow
      40             : // and then something goes wrong and you destroy it and
      41             : // you don't want to bother with a thread dispatch.
      42             : //
      43             : // Eventually we hope to relax the "no listeners"
      44             : // restriction by thread-locking the signals, but previous
      45             : // attempts have caused deadlocks.
      46             : //
      47             : // Most of these invariants are enforced by hard asserts
      48             : // (i.e., those which fire even in production builds).
      49             : 
      50             : namespace mozilla {
      51             : 
      52             : class TransportFlow final : public nsISupports,
      53             :                             public sigslot::has_slots<> {
      54             :  public:
      55             :   TransportFlow()
      56             :     : id_("(anonymous)"),
      57             :       state_(TransportLayer::TS_NONE),
      58             :       layers_(new std::deque<TransportLayer *>) {}
      59           0 :   explicit TransportFlow(const std::string id)
      60           0 :     : id_(id),
      61             :       state_(TransportLayer::TS_NONE),
      62           0 :       layers_(new std::deque<TransportLayer *>) {}
      63             : 
      64           0 :   const std::string& id() const { return id_; }
      65             : 
      66             :   // Layer management. Note PushLayer() is not thread protected, so
      67             :   // either:
      68             :   // (a) Do it in the thread handling the I/O
      69             :   // (b) Do it before you activate the I/O system
      70             :   //
      71             :   // The flow takes ownership of the layers after a successful
      72             :   // push.
      73             :   nsresult PushLayer(TransportLayer *layer);
      74             : 
      75             :   // Convenience function to push multiple layers on. Layers
      76             :   // are pushed on in the order that they are in the queue.
      77             :   // Any failures cause the flow to become inoperable and
      78             :   // destroys all the layers including those already pushed.
      79             :   // TODO(ekr@rtfm.com): Change layers to be ref-counted.
      80             :   nsresult PushLayers(nsAutoPtr<std::queue<TransportLayer *> > layers);
      81             : 
      82             :   TransportLayer *top() const;
      83             :   TransportLayer *GetLayer(const std::string& id) const;
      84             : 
      85             :   // Wrappers for whatever TLayer happens to be the top layer
      86             :   // at the time. This way you don't need to do top()->Foo().
      87             :   TransportLayer::State state(); // Current state
      88             :   TransportResult SendPacket(const unsigned char *data, size_t len);
      89             : 
      90             :   // State has changed. Reflects the top flow.
      91             :   sigslot::signal2<TransportFlow *, TransportLayer::State>
      92             :     SignalStateChange;
      93             : 
      94             :   // Data received on the flow
      95             :   sigslot::signal3<TransportFlow*, const unsigned char *, size_t>
      96             :     SignalPacketReceived;
      97             : 
      98             :   bool Contains(TransportLayer *layer) const;
      99             : 
     100             :   NS_DECL_THREADSAFE_ISUPPORTS
     101             : 
     102             :  private:
     103             :   ~TransportFlow();
     104             : 
     105             :   DISALLOW_COPY_ASSIGN(TransportFlow);
     106             : 
     107             :   // Check if we are on the right thread
     108           0 :   void CheckThread() const {
     109           0 :     if (!CheckThreadInt())
     110           0 :       MOZ_CRASH();
     111           0 :   }
     112             : 
     113           0 :   bool CheckThreadInt() const {
     114             :     bool on;
     115             : 
     116           0 :     if (!target_)  // OK if no thread set.
     117           0 :       return true;
     118           0 :     if (NS_FAILED(target_->IsOnCurrentThread(&on)))
     119           0 :       return false;
     120             : 
     121           0 :     return on;
     122             :   }
     123             : 
     124             :   void EnsureSameThread(TransportLayer *layer);
     125             : 
     126             :   void StateChange(TransportLayer *layer, TransportLayer::State state);
     127             :   void StateChangeInt(TransportLayer::State state);
     128             :   void PacketReceived(TransportLayer* layer, const unsigned char *data,
     129             :       size_t len);
     130             :   static void DestroyFinal(nsAutoPtr<std::deque<TransportLayer *> > layers);
     131             : 
     132             :   // Overload needed because we use deque internally and queue externally.
     133             :   static void ClearLayers(std::deque<TransportLayer *>* layers);
     134             :   static void ClearLayers(std::queue<TransportLayer *>* layers);
     135             : 
     136             :   std::string id_;
     137             :   TransportLayer::State state_;
     138             :   UniquePtr<std::deque<TransportLayer *>> layers_;
     139             :   nsCOMPtr<nsIEventTarget> target_;
     140             : };
     141             : 
     142             : }  // close namespace
     143             : #endif

Generated by: LCOV version 1.13