netwerk/base/src/nsTransportUtils.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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/. */
     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"
    13 using namespace mozilla;
    15 //-----------------------------------------------------------------------------
    17 class nsTransportStatusEvent;
    19 class nsTransportEventSinkProxy : public nsITransportEventSink
    20 {
    21 public:
    22     NS_DECL_THREADSAFE_ISUPPORTS
    23     NS_DECL_NSITRANSPORTEVENTSINK
    25     nsTransportEventSinkProxy(nsITransportEventSink *sink,
    26                               nsIEventTarget *target,
    27                               bool coalesceAll)
    28         : mSink(sink)
    29         , mTarget(target)
    30         , mLock("nsTransportEventSinkProxy.mLock")
    31         , mLastEvent(nullptr)
    32         , mCoalesceAll(coalesceAll)
    33     {
    34         NS_ADDREF(mSink);
    35     }
    37     virtual ~nsTransportEventSinkProxy()
    38     {
    39         // our reference to mSink could be the last, so be sure to release
    40         // it on the target thread.  otherwise, we could get into trouble.
    41         NS_ProxyRelease(mTarget, mSink);
    42     }
    44     nsITransportEventSink           *mSink;
    45     nsCOMPtr<nsIEventTarget>         mTarget;
    46     Mutex                            mLock;
    47     nsTransportStatusEvent          *mLastEvent;
    48     bool                             mCoalesceAll;
    49 };
    51 class nsTransportStatusEvent : public nsRunnable
    52 {
    53 public:
    54     nsTransportStatusEvent(nsTransportEventSinkProxy *proxy,
    55                            nsITransport *transport,
    56                            nsresult status,
    57                            uint64_t progress,
    58                            uint64_t progressMax)
    59         : mProxy(proxy)
    60         , mTransport(transport)
    61         , mStatus(status)
    62         , mProgress(progress)
    63         , mProgressMax(progressMax)
    64     {}
    66     ~nsTransportStatusEvent() {}
    68     NS_IMETHOD Run()
    69     {
    70         // since this event is being handled, we need to clear the proxy's ref.
    71         // if not coalescing all, then last event may not equal self!
    72         {
    73             MutexAutoLock lock(mProxy->mLock);
    74             if (mProxy->mLastEvent == this)
    75                 mProxy->mLastEvent = nullptr;
    76         }
    78         mProxy->mSink->OnTransportStatus(mTransport, mStatus, mProgress,
    79                                          mProgressMax);
    80         return NS_OK;
    81     }
    83     nsRefPtr<nsTransportEventSinkProxy> mProxy;
    85     // parameters to OnTransportStatus
    86     nsCOMPtr<nsITransport> mTransport;
    87     nsresult               mStatus;
    88     uint64_t               mProgress;
    89     uint64_t               mProgressMax;
    90 };
    92 NS_IMPL_ISUPPORTS(nsTransportEventSinkProxy, nsITransportEventSink)
    94 NS_IMETHODIMP
    95 nsTransportEventSinkProxy::OnTransportStatus(nsITransport *transport,
    96                                              nsresult status,
    97                                              uint64_t progress,
    98                                              uint64_t progressMax)
    99 {
   100     nsresult rv = NS_OK;
   101     nsRefPtr<nsTransportStatusEvent> event;
   102     {
   103         MutexAutoLock lock(mLock);
   105         // try to coalesce events! ;-)
   106         if (mLastEvent && (mCoalesceAll || mLastEvent->mStatus == status)) {
   107             mLastEvent->mStatus = status;
   108             mLastEvent->mProgress = progress;
   109             mLastEvent->mProgressMax = progressMax;
   110         }
   111         else {
   112             event = new nsTransportStatusEvent(this, transport, status,
   113                                                progress, progressMax);
   114             if (!event)
   115                 rv = NS_ERROR_OUT_OF_MEMORY;
   116             mLastEvent = event;  // weak ref
   117         }
   118     }
   119     if (event) {
   120         rv = mTarget->Dispatch(event, NS_DISPATCH_NORMAL);
   121         if (NS_FAILED(rv)) {
   122             NS_WARNING("unable to post transport status event");
   124             MutexAutoLock lock(mLock); // cleanup.. don't reference anymore!
   125             mLastEvent = nullptr;
   126         }
   127     }
   128     return rv;
   129 }
   131 //-----------------------------------------------------------------------------
   133 nsresult
   134 net_NewTransportEventSinkProxy(nsITransportEventSink **result,
   135                                nsITransportEventSink *sink,
   136                                nsIEventTarget *target,
   137                                bool coalesceAll)
   138 {
   139     *result = new nsTransportEventSinkProxy(sink, target, coalesceAll);
   140     if (!*result)
   141         return NS_ERROR_OUT_OF_MEMORY;
   142     NS_ADDREF(*result);
   143     return NS_OK;
   144 }

mercurial