Source code

Revision control

Other Tools

1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* This Source Code Form is subject to the terms of the Mozilla Public
3
* License, v. 2.0. If a copy of the MPL was not distributed with this
4
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6
#include "mozilla/DebugOnly.h"
7
8
#include "nscore.h"
9
#include "nsRequestObserverProxy.h"
10
#include "nsIRequest.h"
11
#include "nsAutoPtr.h"
12
#include "mozilla/Logging.h"
13
#include "mozilla/IntegerPrintfMacros.h"
14
15
namespace mozilla {
16
namespace net {
17
18
static LazyLogModule gRequestObserverProxyLog("nsRequestObserverProxy");
19
20
#undef LOG
21
#define LOG(args) MOZ_LOG(gRequestObserverProxyLog, LogLevel::Debug, args)
22
23
//-----------------------------------------------------------------------------
24
// nsARequestObserverEvent internal class...
25
//-----------------------------------------------------------------------------
26
27
nsARequestObserverEvent::nsARequestObserverEvent(nsIRequest* request)
28
: Runnable("net::nsARequestObserverEvent"), mRequest(request) {
29
MOZ_ASSERT(mRequest, "null pointer");
30
}
31
32
//-----------------------------------------------------------------------------
33
// nsOnStartRequestEvent internal class...
34
//-----------------------------------------------------------------------------
35
36
class nsOnStartRequestEvent : public nsARequestObserverEvent {
37
RefPtr<nsRequestObserverProxy> mProxy;
38
39
public:
40
nsOnStartRequestEvent(nsRequestObserverProxy* proxy, nsIRequest* request)
41
: nsARequestObserverEvent(request), mProxy(proxy) {
42
MOZ_ASSERT(mProxy, "null pointer");
43
}
44
45
virtual ~nsOnStartRequestEvent() = default;
46
47
NS_IMETHOD Run() override {
48
LOG(("nsOnStartRequestEvent::HandleEvent [req=%p]\n", mRequest.get()));
49
50
if (!mProxy->mObserver) {
51
MOZ_ASSERT_UNREACHABLE(
52
"already handled onStopRequest event "
53
"(observer is null)");
54
return NS_OK;
55
}
56
57
LOG(("handle startevent=%p\n", this));
58
nsresult rv = mProxy->mObserver->OnStartRequest(mRequest);
59
if (NS_FAILED(rv)) {
60
LOG(("OnStartRequest failed [rv=%" PRIx32 "] canceling request!\n",
61
static_cast<uint32_t>(rv)));
62
rv = mRequest->Cancel(rv);
63
NS_ASSERTION(NS_SUCCEEDED(rv), "Cancel failed for request!");
64
}
65
66
return NS_OK;
67
}
68
};
69
70
//-----------------------------------------------------------------------------
71
// nsOnStopRequestEvent internal class...
72
//-----------------------------------------------------------------------------
73
74
class nsOnStopRequestEvent : public nsARequestObserverEvent {
75
RefPtr<nsRequestObserverProxy> mProxy;
76
77
public:
78
nsOnStopRequestEvent(nsRequestObserverProxy* proxy, nsIRequest* request)
79
: nsARequestObserverEvent(request), mProxy(proxy) {
80
MOZ_ASSERT(mProxy, "null pointer");
81
}
82
83
virtual ~nsOnStopRequestEvent() = default;
84
85
NS_IMETHOD Run() override {
86
LOG(("nsOnStopRequestEvent::HandleEvent [req=%p]\n", mRequest.get()));
87
88
nsMainThreadPtrHandle<nsIRequestObserver> observer = mProxy->mObserver;
89
if (!observer) {
90
MOZ_ASSERT_UNREACHABLE(
91
"already handled onStopRequest event "
92
"(observer is null)");
93
return NS_OK;
94
}
95
// Do not allow any more events to be handled after OnStopRequest
96
mProxy->mObserver = nullptr;
97
98
nsresult status = NS_OK;
99
DebugOnly<nsresult> rv = mRequest->GetStatus(&status);
100
NS_ASSERTION(NS_SUCCEEDED(rv), "GetStatus failed for request!");
101
102
LOG(("handle stopevent=%p\n", this));
103
(void)observer->OnStopRequest(mRequest, status);
104
105
return NS_OK;
106
}
107
};
108
109
//-----------------------------------------------------------------------------
110
// nsRequestObserverProxy::nsISupports implementation...
111
//-----------------------------------------------------------------------------
112
113
NS_IMPL_ISUPPORTS(nsRequestObserverProxy, nsIRequestObserver,
114
nsIRequestObserverProxy)
115
116
//-----------------------------------------------------------------------------
117
// nsRequestObserverProxy::nsIRequestObserver implementation...
118
//-----------------------------------------------------------------------------
119
120
NS_IMETHODIMP
121
nsRequestObserverProxy::OnStartRequest(nsIRequest* request) {
122
LOG(("nsRequestObserverProxy::OnStartRequest [this=%p req=%p]\n", this,
123
request));
124
125
nsOnStartRequestEvent* ev = new nsOnStartRequestEvent(this, request);
126
if (!ev) return NS_ERROR_OUT_OF_MEMORY;
127
128
LOG(("post startevent=%p\n", ev));
129
nsresult rv = FireEvent(ev);
130
if (NS_FAILED(rv)) delete ev;
131
return rv;
132
}
133
134
NS_IMETHODIMP
135
nsRequestObserverProxy::OnStopRequest(nsIRequest* request, nsresult status) {
136
LOG(("nsRequestObserverProxy: OnStopRequest [this=%p req=%p status=%" PRIx32
137
"]\n",
138
this, request, static_cast<uint32_t>(status)));
139
140
// The status argument is ignored because, by the time the OnStopRequestEvent
141
// is actually processed, the status of the request may have changed :-(
142
// To make sure that an accurate status code is always used, GetStatus() is
143
// called when the OnStopRequestEvent is actually processed (see above).
144
145
nsOnStopRequestEvent* ev = new nsOnStopRequestEvent(this, request);
146
if (!ev) return NS_ERROR_OUT_OF_MEMORY;
147
148
LOG(("post stopevent=%p\n", ev));
149
nsresult rv = FireEvent(ev);
150
if (NS_FAILED(rv)) delete ev;
151
return rv;
152
}
153
154
//-----------------------------------------------------------------------------
155
// nsRequestObserverProxy::nsIRequestObserverProxy implementation...
156
//-----------------------------------------------------------------------------
157
158
NS_IMETHODIMP
159
nsRequestObserverProxy::Init(nsIRequestObserver* observer,
160
nsISupports* context) {
161
NS_ENSURE_ARG_POINTER(observer);
162
mObserver = new nsMainThreadPtrHolder<nsIRequestObserver>(
163
"nsRequestObserverProxy::mObserver", observer);
164
mContext = new nsMainThreadPtrHolder<nsISupports>(
165
"nsRequestObserverProxy::mContext", context);
166
167
return NS_OK;
168
}
169
170
//-----------------------------------------------------------------------------
171
// nsRequestObserverProxy implementation...
172
//-----------------------------------------------------------------------------
173
174
nsresult nsRequestObserverProxy::FireEvent(nsARequestObserverEvent* event) {
175
nsCOMPtr<nsIEventTarget> mainThread(GetMainThreadEventTarget());
176
return mainThread->Dispatch(event, NS_DISPATCH_NORMAL);
177
}
178
179
} // namespace net
180
} // namespace mozilla