Bug 1878930 - s/RawBuffer/Span/: TexImage: GetRangeFromData. r=gfx-reviewers,lsalzman
[gecko.git] / netwerk / base / nsTransportUtils.cpp
blobdf53ead1986a994c27bbddb3c5534cd22859e8dc
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 "nsCOMPtr.h"
7 #include "nsITransport.h"
8 #include "nsProxyRelease.h"
9 #include "nsSocketTransportService2.h"
10 #include "nsThreadUtils.h"
11 #include "nsTransportUtils.h"
13 using namespace mozilla;
15 //-----------------------------------------------------------------------------
17 class nsTransportStatusEvent;
19 class nsTransportEventSinkProxy : public nsITransportEventSink {
20 public:
21 NS_DECL_THREADSAFE_ISUPPORTS
22 NS_DECL_NSITRANSPORTEVENTSINK
24 nsTransportEventSinkProxy(nsITransportEventSink* sink, nsIEventTarget* target)
25 : mSink(sink),
26 mTarget(target),
27 mLock("nsTransportEventSinkProxy.mLock"),
28 mLastEvent(nullptr) {
29 NS_ADDREF(mSink);
32 private:
33 virtual ~nsTransportEventSinkProxy() {
34 // our reference to mSink could be the last, so be sure to release
35 // it on the target thread. otherwise, we could get into trouble.
36 NS_ProxyRelease("nsTransportEventSinkProxy::mSink", mTarget,
37 dont_AddRef(mSink));
40 public:
41 nsITransportEventSink* mSink;
42 nsCOMPtr<nsIEventTarget> mTarget;
43 Mutex mLock MOZ_UNANNOTATED;
44 nsTransportStatusEvent* mLastEvent;
47 class nsTransportStatusEvent : public Runnable {
48 public:
49 nsTransportStatusEvent(nsTransportEventSinkProxy* proxy,
50 nsITransport* transport, nsresult status,
51 int64_t progress, int64_t progressMax)
52 : Runnable("nsTransportStatusEvent"),
53 mProxy(proxy),
54 mTransport(transport),
55 mStatus(status),
56 mProgress(progress),
57 mProgressMax(progressMax) {}
59 ~nsTransportStatusEvent() {
60 auto ReleaseTransport = [transport(std::move(mTransport))]() mutable {};
61 if (!net::OnSocketThread()) {
62 net::gSocketTransportService->Dispatch(NS_NewRunnableFunction(
63 "nsHttpConnection::~nsHttpConnection", std::move(ReleaseTransport)));
67 NS_IMETHOD Run() override {
68 // since this event is being handled, we need to clear the proxy's ref.
69 // if not coalescing all, then last event may not equal self!
71 MutexAutoLock lock(mProxy->mLock);
72 if (mProxy->mLastEvent == this) mProxy->mLastEvent = nullptr;
75 mProxy->mSink->OnTransportStatus(mTransport, mStatus, mProgress,
76 mProgressMax);
77 return NS_OK;
80 RefPtr<nsTransportEventSinkProxy> mProxy;
82 // parameters to OnTransportStatus
83 nsCOMPtr<nsITransport> mTransport;
84 nsresult mStatus;
85 int64_t mProgress;
86 int64_t mProgressMax;
89 NS_IMPL_ISUPPORTS(nsTransportEventSinkProxy, nsITransportEventSink)
91 NS_IMETHODIMP
92 nsTransportEventSinkProxy::OnTransportStatus(nsITransport* transport,
93 nsresult status, int64_t progress,
94 int64_t progressMax) {
95 nsresult rv = NS_OK;
96 RefPtr<nsTransportStatusEvent> event;
98 MutexAutoLock lock(mLock);
100 // try to coalesce events! ;-)
101 if (mLastEvent && (mLastEvent->mStatus == status)) {
102 mLastEvent->mStatus = status;
103 mLastEvent->mProgress = progress;
104 mLastEvent->mProgressMax = progressMax;
105 } else {
106 event = new nsTransportStatusEvent(this, transport, status, progress,
107 progressMax);
108 if (!event) rv = NS_ERROR_OUT_OF_MEMORY;
109 mLastEvent = event; // weak ref
112 if (event) {
113 rv = mTarget->Dispatch(event, NS_DISPATCH_NORMAL);
114 if (NS_FAILED(rv)) {
115 NS_WARNING("unable to post transport status event");
117 MutexAutoLock lock(mLock); // cleanup.. don't reference anymore!
118 mLastEvent = nullptr;
121 return rv;
124 //-----------------------------------------------------------------------------
126 nsresult net_NewTransportEventSinkProxy(nsITransportEventSink** result,
127 nsITransportEventSink* sink,
128 nsIEventTarget* target) {
129 RefPtr<nsTransportEventSinkProxy> res =
130 new nsTransportEventSinkProxy(sink, target);
131 res.forget(result);
132 return NS_OK;