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"
13 using namespace mozilla
;
15 //-----------------------------------------------------------------------------
17 class nsTransportStatusEvent
;
19 class nsTransportEventSinkProxy
: public nsITransportEventSink
23 NS_DECL_NSITRANSPORTEVENTSINK
25 nsTransportEventSinkProxy(nsITransportEventSink
*sink
,
26 nsIEventTarget
*target
,
30 , mLock("nsTransportEventSinkProxy.mLock")
32 , mCoalesceAll(coalesceAll
)
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
;
47 nsTransportStatusEvent
*mLastEvent
;
51 class nsTransportStatusEvent
: public nsRunnable
54 nsTransportStatusEvent(nsTransportEventSinkProxy
*proxy
,
55 nsITransport
*transport
,
60 , mTransport(transport
)
63 , mProgressMax(progressMax
)
66 ~nsTransportStatusEvent() {}
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
,
83 nsRefPtr
<nsTransportEventSinkProxy
> mProxy
;
85 // parameters to OnTransportStatus
86 nsCOMPtr
<nsITransport
> mTransport
;
89 uint64_t mProgressMax
;
92 NS_IMPL_THREADSAFE_ISUPPORTS1(nsTransportEventSinkProxy
, nsITransportEventSink
)
95 nsTransportEventSinkProxy::OnTransportStatus(nsITransport
*transport
,
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
;
112 event
= new nsTransportStatusEvent(this, transport
, status
,
113 progress
, progressMax
);
115 rv
= NS_ERROR_OUT_OF_MEMORY
;
116 mLastEvent
= event
; // weak ref
120 rv
= mTarget
->Dispatch(event
, NS_DISPATCH_NORMAL
);
122 NS_WARNING("unable to post transport status event");
124 MutexAutoLock
lock(mLock
); // cleanup.. don't reference anymore!
125 mLastEvent
= nullptr;
131 //-----------------------------------------------------------------------------
134 net_NewTransportEventSinkProxy(nsITransportEventSink
**result
,
135 nsITransportEventSink
*sink
,
136 nsIEventTarget
*target
,
139 *result
= new nsTransportEventSinkProxy(sink
, target
, coalesceAll
);
141 return NS_ERROR_OUT_OF_MEMORY
;