Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 0 : nsARequestObserverEvent::nsARequestObserverEvent(nsIRequest* request)
28 : : Runnable("net::nsARequestObserverEvent")
29 0 : , mRequest(request)
30 : {
31 0 : NS_PRECONDITION(mRequest, "null pointer");
32 0 : }
33 :
34 : //-----------------------------------------------------------------------------
35 : // nsOnStartRequestEvent internal class...
36 : //-----------------------------------------------------------------------------
37 :
38 : class nsOnStartRequestEvent : public nsARequestObserverEvent
39 : {
40 : RefPtr<nsRequestObserverProxy> mProxy;
41 : public:
42 0 : nsOnStartRequestEvent(nsRequestObserverProxy *proxy,
43 : nsIRequest *request)
44 0 : : nsARequestObserverEvent(request)
45 0 : , mProxy(proxy)
46 : {
47 0 : NS_PRECONDITION(mProxy, "null pointer");
48 0 : }
49 :
50 0 : virtual ~nsOnStartRequestEvent() {}
51 :
52 0 : NS_IMETHOD Run() override
53 : {
54 0 : LOG(("nsOnStartRequestEvent::HandleEvent [req=%p]\n", mRequest.get()));
55 :
56 0 : if (!mProxy->mObserver) {
57 0 : NS_NOTREACHED("already handled onStopRequest event (observer is null)");
58 0 : return NS_OK;
59 : }
60 :
61 0 : LOG(("handle startevent=%p\n", this));
62 0 : nsresult rv = mProxy->mObserver->OnStartRequest(mRequest, mProxy->mContext);
63 0 : if (NS_FAILED(rv)) {
64 0 : LOG(("OnStartRequest failed [rv=%" PRIx32 "] canceling request!\n",
65 : static_cast<uint32_t>(rv)));
66 0 : rv = mRequest->Cancel(rv);
67 0 : NS_ASSERTION(NS_SUCCEEDED(rv), "Cancel failed for request!");
68 : }
69 :
70 0 : return NS_OK;
71 : }
72 : };
73 :
74 : //-----------------------------------------------------------------------------
75 : // nsOnStopRequestEvent internal class...
76 : //-----------------------------------------------------------------------------
77 :
78 : class nsOnStopRequestEvent : public nsARequestObserverEvent
79 : {
80 : RefPtr<nsRequestObserverProxy> mProxy;
81 : public:
82 0 : nsOnStopRequestEvent(nsRequestObserverProxy *proxy,
83 : nsIRequest *request)
84 0 : : nsARequestObserverEvent(request)
85 0 : , mProxy(proxy)
86 : {
87 0 : NS_PRECONDITION(mProxy, "null pointer");
88 0 : }
89 :
90 0 : virtual ~nsOnStopRequestEvent() {}
91 :
92 0 : NS_IMETHOD Run() override
93 : {
94 0 : LOG(("nsOnStopRequestEvent::HandleEvent [req=%p]\n", mRequest.get()));
95 :
96 0 : nsMainThreadPtrHandle<nsIRequestObserver> observer = mProxy->mObserver;
97 0 : if (!observer) {
98 0 : NS_NOTREACHED("already handled onStopRequest event (observer is null)");
99 0 : return NS_OK;
100 : }
101 : // Do not allow any more events to be handled after OnStopRequest
102 0 : mProxy->mObserver = 0;
103 :
104 0 : nsresult status = NS_OK;
105 0 : DebugOnly<nsresult> rv = mRequest->GetStatus(&status);
106 0 : NS_ASSERTION(NS_SUCCEEDED(rv), "GetStatus failed for request!");
107 :
108 0 : LOG(("handle stopevent=%p\n", this));
109 0 : (void) observer->OnStopRequest(mRequest, mProxy->mContext, status);
110 :
111 0 : return NS_OK;
112 : }
113 : };
114 :
115 : //-----------------------------------------------------------------------------
116 : // nsRequestObserverProxy::nsISupports implementation...
117 : //-----------------------------------------------------------------------------
118 :
119 0 : NS_IMPL_ISUPPORTS(nsRequestObserverProxy,
120 : nsIRequestObserver,
121 : nsIRequestObserverProxy)
122 :
123 : //-----------------------------------------------------------------------------
124 : // nsRequestObserverProxy::nsIRequestObserver implementation...
125 : //-----------------------------------------------------------------------------
126 :
127 : NS_IMETHODIMP
128 0 : nsRequestObserverProxy::OnStartRequest(nsIRequest *request,
129 : nsISupports *context)
130 : {
131 0 : MOZ_ASSERT(!context || context == mContext);
132 0 : LOG(("nsRequestObserverProxy::OnStartRequest [this=%p req=%p]\n", this, request));
133 :
134 : nsOnStartRequestEvent *ev =
135 0 : new nsOnStartRequestEvent(this, request);
136 0 : if (!ev)
137 0 : return NS_ERROR_OUT_OF_MEMORY;
138 :
139 0 : LOG(("post startevent=%p\n", ev));
140 0 : nsresult rv = FireEvent(ev);
141 0 : if (NS_FAILED(rv))
142 0 : delete ev;
143 0 : return rv;
144 : }
145 :
146 : NS_IMETHODIMP
147 0 : nsRequestObserverProxy::OnStopRequest(nsIRequest *request,
148 : nsISupports *context,
149 : nsresult status)
150 : {
151 0 : MOZ_ASSERT(!context || context == mContext);
152 0 : LOG(("nsRequestObserverProxy: OnStopRequest [this=%p req=%p status=%" PRIx32 "]\n",
153 : this, request, static_cast<uint32_t>(status)));
154 :
155 : // The status argument is ignored because, by the time the OnStopRequestEvent
156 : // is actually processed, the status of the request may have changed :-(
157 : // To make sure that an accurate status code is always used, GetStatus() is
158 : // called when the OnStopRequestEvent is actually processed (see above).
159 :
160 : nsOnStopRequestEvent *ev =
161 0 : new nsOnStopRequestEvent(this, request);
162 0 : if (!ev)
163 0 : return NS_ERROR_OUT_OF_MEMORY;
164 :
165 0 : LOG(("post stopevent=%p\n", ev));
166 0 : nsresult rv = FireEvent(ev);
167 0 : if (NS_FAILED(rv))
168 0 : delete ev;
169 0 : return rv;
170 : }
171 :
172 : //-----------------------------------------------------------------------------
173 : // nsRequestObserverProxy::nsIRequestObserverProxy implementation...
174 : //-----------------------------------------------------------------------------
175 :
176 : NS_IMETHODIMP
177 0 : nsRequestObserverProxy::Init(nsIRequestObserver *observer, nsISupports *context)
178 : {
179 0 : NS_ENSURE_ARG_POINTER(observer);
180 : mObserver = new nsMainThreadPtrHolder<nsIRequestObserver>(
181 0 : "nsRequestObserverProxy::mObserver", observer);
182 : mContext = new nsMainThreadPtrHolder<nsISupports>(
183 0 : "nsRequestObserverProxy::mContext", context);
184 :
185 0 : return NS_OK;
186 : }
187 :
188 : //-----------------------------------------------------------------------------
189 : // nsRequestObserverProxy implementation...
190 : //-----------------------------------------------------------------------------
191 :
192 : nsresult
193 0 : nsRequestObserverProxy::FireEvent(nsARequestObserverEvent *event)
194 : {
195 0 : nsCOMPtr<nsIEventTarget> mainThread(GetMainThreadEventTarget());
196 0 : return mainThread->Dispatch(event, NS_DISPATCH_NORMAL);
197 : }
198 :
199 : } // namespace net
200 : } // namespace mozilla
|