LCOV - code coverage report
Current view: top level - netwerk/base - nsTransportUtils.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 40 48 83.3 %
Date: 2017-07-14 16:53:18 Functions: 12 12 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* This Source Code Form is subject to the terms of the Mozilla Public
       2             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       3             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       4             : 
       5             : #include "mozilla/Mutex.h"
       6             : #include "nsTransportUtils.h"
       7             : #include "nsITransport.h"
       8             : #include "nsProxyRelease.h"
       9             : #include "nsThreadUtils.h"
      10             : #include "nsAutoPtr.h"
      11             : #include "nsCOMPtr.h"
      12             : 
      13             : using namespace mozilla;
      14             : 
      15             : //-----------------------------------------------------------------------------
      16             : 
      17             : class nsTransportStatusEvent;
      18             : 
      19             : class nsTransportEventSinkProxy : public nsITransportEventSink
      20             : {
      21             : public:
      22             :     NS_DECL_THREADSAFE_ISUPPORTS
      23             :     NS_DECL_NSITRANSPORTEVENTSINK
      24             : 
      25           3 :     nsTransportEventSinkProxy(nsITransportEventSink *sink,
      26             :                               nsIEventTarget *target)
      27           3 :         : mSink(sink)
      28             :         , mTarget(target)
      29             :         , mLock("nsTransportEventSinkProxy.mLock")
      30           3 :         , mLastEvent(nullptr)
      31             :     {
      32           3 :         NS_ADDREF(mSink);
      33           3 :     }
      34             : 
      35             : private:
      36           6 :     virtual ~nsTransportEventSinkProxy()
      37           6 :     {
      38             :         // our reference to mSink could be the last, so be sure to release
      39             :         // it on the target thread.  otherwise, we could get into trouble.
      40           3 :         NS_ProxyRelease(
      41           6 :           "nsTransportEventSinkProxy::mSink", mTarget, dont_AddRef(mSink));
      42           9 :     }
      43             : 
      44             : public:
      45             :     nsITransportEventSink           *mSink;
      46             :     nsCOMPtr<nsIEventTarget>         mTarget;
      47             :     Mutex                            mLock;
      48             :     nsTransportStatusEvent          *mLastEvent;
      49             : };
      50             : 
      51             : class nsTransportStatusEvent : public Runnable
      52             : {
      53             : public:
      54          16 :     nsTransportStatusEvent(nsTransportEventSinkProxy *proxy,
      55             :                            nsITransport *transport,
      56             :                            nsresult status,
      57             :                            int64_t progress,
      58             :                            int64_t progressMax)
      59          16 :         : Runnable("nsTransportStatusEvent")
      60             :         , mProxy(proxy)
      61             :         , mTransport(transport)
      62             :         , mStatus(status)
      63             :         , mProgress(progress)
      64          16 :         , mProgressMax(progressMax)
      65          16 :     {}
      66             : 
      67          48 :     ~nsTransportStatusEvent() {}
      68             : 
      69          16 :     NS_IMETHOD Run() override
      70             :     {
      71             :         // since this event is being handled, we need to clear the proxy's ref.
      72             :         // if not coalescing all, then last event may not equal self!
      73             :         {
      74          32 :             MutexAutoLock lock(mProxy->mLock);
      75          16 :             if (mProxy->mLastEvent == this)
      76           3 :                 mProxy->mLastEvent = nullptr;
      77             :         }
      78             : 
      79          32 :         mProxy->mSink->OnTransportStatus(mTransport, mStatus, mProgress,
      80          32 :                                          mProgressMax);
      81          16 :         return NS_OK;
      82             :     }
      83             : 
      84             :     RefPtr<nsTransportEventSinkProxy> mProxy;
      85             : 
      86             :     // parameters to OnTransportStatus
      87             :     nsCOMPtr<nsITransport> mTransport;
      88             :     nsresult               mStatus;
      89             :     int64_t                mProgress;
      90             :     int64_t                mProgressMax;
      91             : };
      92             : 
      93          47 : NS_IMPL_ISUPPORTS(nsTransportEventSinkProxy, nsITransportEventSink)
      94             : 
      95             : NS_IMETHODIMP
      96          16 : nsTransportEventSinkProxy::OnTransportStatus(nsITransport *transport,
      97             :                                              nsresult status,
      98             :                                              int64_t progress,
      99             :                                              int64_t progressMax)
     100             : {
     101          16 :     nsresult rv = NS_OK;
     102          32 :     RefPtr<nsTransportStatusEvent> event;
     103             :     {
     104          32 :         MutexAutoLock lock(mLock);
     105             : 
     106             :         // try to coalesce events! ;-)
     107          16 :         if (mLastEvent && (mLastEvent->mStatus == status)) {
     108           0 :             mLastEvent->mStatus = status;
     109           0 :             mLastEvent->mProgress = progress;
     110           0 :             mLastEvent->mProgressMax = progressMax;
     111             :         }
     112             :         else {
     113             :             event = new nsTransportStatusEvent(this, transport, status,
     114          16 :                                                progress, progressMax);
     115          16 :             if (!event)
     116           0 :                 rv = NS_ERROR_OUT_OF_MEMORY;
     117          16 :             mLastEvent = event;  // weak ref
     118             :         }
     119             :     }
     120          16 :     if (event) {
     121          16 :         rv = mTarget->Dispatch(event, NS_DISPATCH_NORMAL);
     122          16 :         if (NS_FAILED(rv)) {
     123           0 :             NS_WARNING("unable to post transport status event");
     124             : 
     125           0 :             MutexAutoLock lock(mLock); // cleanup.. don't reference anymore!
     126           0 :             mLastEvent = nullptr;
     127             :         }
     128             :     }
     129          32 :     return rv;
     130             : }
     131             : 
     132             : //-----------------------------------------------------------------------------
     133             : 
     134             : nsresult
     135           3 : net_NewTransportEventSinkProxy(nsITransportEventSink **result,
     136             :                                nsITransportEventSink *sink,
     137             :                                nsIEventTarget *target)
     138             : {
     139           3 :     *result = new nsTransportEventSinkProxy(sink, target);
     140           3 :     if (!*result)
     141           0 :         return NS_ERROR_OUT_OF_MEMORY;
     142           3 :     NS_ADDREF(*result);
     143           3 :     return NS_OK;
     144             : }

Generated by: LCOV version 1.13