nsRequestObserverProxy.cpp (6194B)
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 "mozilla/Logging.h" 12 #include "mozilla/IntegerPrintfMacros.h" 13 14 namespace mozilla { 15 namespace net { 16 17 static LazyLogModule gRequestObserverProxyLog("nsRequestObserverProxy"); 18 19 #undef LOG 20 #define LOG(args) MOZ_LOG(gRequestObserverProxyLog, LogLevel::Debug, args) 21 22 //----------------------------------------------------------------------------- 23 // nsARequestObserverEvent internal class... 24 //----------------------------------------------------------------------------- 25 26 nsARequestObserverEvent::nsARequestObserverEvent(nsIRequest* request) 27 : Runnable("net::nsARequestObserverEvent"), mRequest(request) { 28 MOZ_ASSERT(mRequest, "null pointer"); 29 } 30 31 //----------------------------------------------------------------------------- 32 // nsOnStartRequestEvent internal class... 33 //----------------------------------------------------------------------------- 34 35 class nsOnStartRequestEvent : public nsARequestObserverEvent { 36 RefPtr<nsRequestObserverProxy> mProxy; 37 38 public: 39 nsOnStartRequestEvent(nsRequestObserverProxy* proxy, nsIRequest* request) 40 : nsARequestObserverEvent(request), mProxy(proxy) { 41 MOZ_ASSERT(mProxy, "null pointer"); 42 } 43 44 NS_IMETHOD Run() override { 45 LOG(("nsOnStartRequestEvent::HandleEvent [req=%p]\n", mRequest.get())); 46 47 if (!mProxy->mObserver) { 48 MOZ_ASSERT_UNREACHABLE( 49 "already handled onStopRequest event " 50 "(observer is null)"); 51 return NS_OK; 52 } 53 54 LOG(("handle startevent=%p\n", this)); 55 nsresult rv = mProxy->mObserver->OnStartRequest(mRequest); 56 if (NS_FAILED(rv)) { 57 LOG(("OnStartRequest failed [rv=%" PRIx32 "] canceling request!\n", 58 static_cast<uint32_t>(rv))); 59 rv = mRequest->Cancel(rv); 60 NS_ASSERTION(NS_SUCCEEDED(rv), "Cancel failed for request!"); 61 } 62 63 return NS_OK; 64 } 65 66 private: 67 virtual ~nsOnStartRequestEvent() = default; 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 NS_IMETHOD Run() override { 84 LOG(("nsOnStopRequestEvent::HandleEvent [req=%p]\n", mRequest.get())); 85 86 nsMainThreadPtrHandle<nsIRequestObserver> observer = mProxy->mObserver; 87 if (!observer) { 88 MOZ_ASSERT_UNREACHABLE( 89 "already handled onStopRequest event " 90 "(observer is null)"); 91 return NS_OK; 92 } 93 // Do not allow any more events to be handled after OnStopRequest 94 mProxy->mObserver = nullptr; 95 96 nsresult status = NS_OK; 97 DebugOnly<nsresult> rv = mRequest->GetStatus(&status); 98 NS_ASSERTION(NS_SUCCEEDED(rv), "GetStatus failed for request!"); 99 100 LOG(("handle stopevent=%p\n", this)); 101 (void)observer->OnStopRequest(mRequest, status); 102 103 return NS_OK; 104 } 105 106 private: 107 virtual ~nsOnStopRequestEvent() = default; 108 }; 109 110 //----------------------------------------------------------------------------- 111 // nsRequestObserverProxy::nsISupports implementation... 112 //----------------------------------------------------------------------------- 113 114 NS_IMPL_ISUPPORTS(nsRequestObserverProxy, nsIRequestObserver, 115 nsIRequestObserverProxy) 116 117 //----------------------------------------------------------------------------- 118 // nsRequestObserverProxy::nsIRequestObserver implementation... 119 //----------------------------------------------------------------------------- 120 121 NS_IMETHODIMP 122 nsRequestObserverProxy::OnStartRequest(nsIRequest* request) { 123 LOG(("nsRequestObserverProxy::OnStartRequest [this=%p req=%p]\n", this, 124 request)); 125 126 RefPtr<nsOnStartRequestEvent> ev = new nsOnStartRequestEvent(this, request); 127 128 LOG(("post startevent=%p\n", ev.get())); 129 return FireEvent(ev); 130 } 131 132 NS_IMETHODIMP 133 nsRequestObserverProxy::OnStopRequest(nsIRequest* request, nsresult status) { 134 LOG(("nsRequestObserverProxy: OnStopRequest [this=%p req=%p status=%" PRIx32 135 "]\n", 136 this, request, static_cast<uint32_t>(status))); 137 138 // The status argument is ignored because, by the time the OnStopRequestEvent 139 // is actually processed, the status of the request may have changed :-( 140 // To make sure that an accurate status code is always used, GetStatus() is 141 // called when the OnStopRequestEvent is actually processed (see above). 142 143 RefPtr<nsOnStopRequestEvent> ev = new nsOnStopRequestEvent(this, request); 144 145 LOG(("post stopevent=%p\n", ev.get())); 146 return FireEvent(ev); 147 } 148 149 //----------------------------------------------------------------------------- 150 // nsRequestObserverProxy::nsIRequestObserverProxy implementation... 151 //----------------------------------------------------------------------------- 152 153 NS_IMETHODIMP 154 nsRequestObserverProxy::Init(nsIRequestObserver* observer, 155 nsISupports* context) { 156 NS_ENSURE_ARG_POINTER(observer); 157 mObserver = new nsMainThreadPtrHolder<nsIRequestObserver>( 158 "nsRequestObserverProxy::mObserver", observer); 159 mContext = new nsMainThreadPtrHolder<nsISupports>( 160 "nsRequestObserverProxy::mContext", context); 161 162 return NS_OK; 163 } 164 165 //----------------------------------------------------------------------------- 166 // nsRequestObserverProxy implementation... 167 //----------------------------------------------------------------------------- 168 169 nsresult nsRequestObserverProxy::FireEvent(nsARequestObserverEvent* event) { 170 nsCOMPtr<nsIEventTarget> mainThread(GetMainThreadSerialEventTarget()); 171 return mainThread->Dispatch(event, NS_DISPATCH_NORMAL); 172 } 173 174 } // namespace net 175 } // namespace mozilla