nsHtml5StreamListener.cpp (3492B)
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/. */ 4 5 #include "nsHtml5StreamListener.h" 6 7 #include "nsHtml5StreamParserReleaser.h" 8 9 NS_IMPL_ADDREF(nsHtml5StreamListener) 10 NS_IMPL_RELEASE(nsHtml5StreamListener) 11 12 NS_INTERFACE_MAP_BEGIN(nsHtml5StreamListener) 13 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIRequestObserver) 14 NS_INTERFACE_MAP_ENTRY(nsIRequestObserver) 15 NS_INTERFACE_MAP_ENTRY(nsIStreamListener) 16 NS_INTERFACE_MAP_ENTRY(nsIThreadRetargetableStreamListener) 17 NS_INTERFACE_MAP_END 18 19 nsHtml5StreamListener::nsHtml5StreamListener(nsHtml5StreamParser* aDelegate) 20 : mDelegateMonitor("nsHtml5StreamListener mDelegateMonitor"), 21 mDelegate(aDelegate) { 22 MOZ_ASSERT(aDelegate, "Must have delegate"); 23 aDelegate->AddRef(); 24 } 25 26 nsHtml5StreamListener::~nsHtml5StreamListener() { DropDelegateImpl(); } 27 28 void nsHtml5StreamListener::DropDelegate() { 29 MOZ_ASSERT(NS_IsMainThread(), 30 "Must not call DropDelegate from non-main threads."); 31 DropDelegateImpl(); 32 } 33 34 void nsHtml5StreamListener::DropDelegateImpl() { 35 mozilla::ReentrantMonitorAutoEnter autoEnter(mDelegateMonitor); 36 if (mDelegate) { 37 nsCOMPtr<nsIRunnable> releaser = new nsHtml5StreamParserReleaser(mDelegate); 38 if (NS_FAILED(((nsHtml5StreamParser*)mDelegate) 39 ->DispatchToMain(releaser.forget()))) { 40 NS_WARNING("Failed to dispatch releaser event."); 41 } 42 mDelegate = nullptr; 43 } 44 } 45 46 nsHtml5StreamParser* nsHtml5StreamListener::GetDelegate() { 47 MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!"); 48 // Since this can be called only on the main 49 // thread and DropDelegate() can only be called on the main thread 50 // it's OK that the monitor here doesn't protect the use of the 51 // return value. 52 return mDelegate; 53 } 54 55 NS_IMETHODIMP 56 nsHtml5StreamListener::CheckListenerChain() { 57 if (MOZ_UNLIKELY(!mDelegate)) { 58 return NS_ERROR_NOT_AVAILABLE; 59 } 60 return NS_OK; 61 } 62 63 NS_IMETHODIMP 64 nsHtml5StreamListener::OnStartRequest(nsIRequest* aRequest) { 65 mozilla::ReentrantMonitorAutoEnter autoEnter(mDelegateMonitor); 66 if (MOZ_UNLIKELY(!mDelegate)) { 67 return NS_ERROR_NOT_AVAILABLE; 68 } 69 return ((nsHtml5StreamParser*)mDelegate)->OnStartRequest(aRequest); 70 } 71 72 NS_IMETHODIMP 73 nsHtml5StreamListener::OnStopRequest(nsIRequest* aRequest, nsresult aStatus) { 74 mozilla::ReentrantMonitorAutoEnter autoEnter(mDelegateMonitor); 75 if (MOZ_UNLIKELY(!mDelegate)) { 76 return NS_ERROR_NOT_AVAILABLE; 77 } 78 return ((nsHtml5StreamParser*)mDelegate) 79 ->OnStopRequest(aRequest, aStatus, autoEnter); 80 } 81 82 NS_IMETHODIMP 83 nsHtml5StreamListener::OnDataAvailable(nsIRequest* aRequest, 84 nsIInputStream* aInStream, 85 uint64_t aSourceOffset, 86 uint32_t aLength) { 87 mozilla::ReentrantMonitorAutoEnter autoEnter(mDelegateMonitor); 88 if (MOZ_UNLIKELY(!mDelegate)) { 89 return NS_ERROR_NOT_AVAILABLE; 90 } 91 return ((nsHtml5StreamParser*)mDelegate) 92 ->OnDataAvailable(aRequest, aInStream, aSourceOffset, aLength); 93 } 94 95 NS_IMETHODIMP 96 nsHtml5StreamListener::OnDataFinished(nsresult aStatus) { 97 mozilla::ReentrantMonitorAutoEnter autoEnter(mDelegateMonitor); 98 99 if (MOZ_UNLIKELY(!mDelegate)) { 100 return NS_ERROR_NOT_AVAILABLE; 101 } 102 103 return ((nsHtml5StreamParser*)mDelegate) 104 ->OnStopRequest(nullptr, aStatus, autoEnter); 105 }