Bug 785860 - fix sts preload list tests to skip private mode tests if private browsin...
[gecko.git] / netwerk / base / src / nsTransportUtils.cpp
blob1b1845d32ac2631beda26bccb9b6fae4a29eed1d
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
21 public:
22 NS_DECL_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)
34 NS_ADDREF(mSink);
37 virtual ~nsTransportEventSinkProxy()
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);
44 nsITransportEventSink *mSink;
45 nsCOMPtr<nsIEventTarget> mTarget;
46 Mutex mLock;
47 nsTransportStatusEvent *mLastEvent;
48 bool mCoalesceAll;
51 class nsTransportStatusEvent : public nsRunnable
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)
66 ~nsTransportStatusEvent() {}
68 NS_IMETHOD Run()
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!
73 MutexAutoLock lock(mProxy->mLock);
74 if (mProxy->mLastEvent == this)
75 mProxy->mLastEvent = nullptr;
78 mProxy->mSink->OnTransportStatus(mTransport, mStatus, mProgress,
79 mProgressMax);
80 return NS_OK;
83 nsRefPtr<nsTransportEventSinkProxy> mProxy;
85 // parameters to OnTransportStatus
86 nsCOMPtr<nsITransport> mTransport;
87 nsresult mStatus;
88 uint64_t mProgress;
89 uint64_t mProgressMax;
92 NS_IMPL_THREADSAFE_ISUPPORTS1(nsTransportEventSinkProxy, nsITransportEventSink)
94 NS_IMETHODIMP
95 nsTransportEventSinkProxy::OnTransportStatus(nsITransport *transport,
96 nsresult status,
97 uint64_t progress,
98 uint64_t progressMax)
100 nsresult rv = NS_OK;
101 nsRefPtr<nsTransportStatusEvent> event;
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;
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
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;
128 return rv;
131 //-----------------------------------------------------------------------------
133 nsresult
134 net_NewTransportEventSinkProxy(nsITransportEventSink **result,
135 nsITransportEventSink *sink,
136 nsIEventTarget *target,
137 bool coalesceAll)
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;