summaryrefslogtreecommitdiffstats
path: root/parser/html/nsHtml5StreamListener.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'parser/html/nsHtml5StreamListener.cpp')
-rw-r--r--parser/html/nsHtml5StreamListener.cpp92
1 files changed, 92 insertions, 0 deletions
diff --git a/parser/html/nsHtml5StreamListener.cpp b/parser/html/nsHtml5StreamListener.cpp
new file mode 100644
index 0000000000..86e18c0296
--- /dev/null
+++ b/parser/html/nsHtml5StreamListener.cpp
@@ -0,0 +1,92 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsHtml5StreamListener.h"
+
+#include "nsHtml5StreamParserReleaser.h"
+
+NS_IMPL_ADDREF(nsHtml5StreamListener)
+NS_IMPL_RELEASE(nsHtml5StreamListener)
+
+NS_INTERFACE_MAP_BEGIN(nsHtml5StreamListener)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIRequestObserver)
+ NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
+ NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
+ NS_INTERFACE_MAP_ENTRY(nsIThreadRetargetableStreamListener)
+NS_INTERFACE_MAP_END
+
+nsHtml5StreamListener::nsHtml5StreamListener(nsHtml5StreamParser* aDelegate)
+ : mDelegateMonitor("nsHtml5StreamListener mDelegateMonitor"),
+ mDelegate(aDelegate) {
+ MOZ_ASSERT(aDelegate, "Must have delegate");
+ aDelegate->AddRef();
+}
+
+nsHtml5StreamListener::~nsHtml5StreamListener() { DropDelegateImpl(); }
+
+void nsHtml5StreamListener::DropDelegate() {
+ MOZ_ASSERT(NS_IsMainThread(),
+ "Must not call DropDelegate from non-main threads.");
+ DropDelegateImpl();
+}
+
+void nsHtml5StreamListener::DropDelegateImpl() {
+ mozilla::ReentrantMonitorAutoEnter autoEnter(mDelegateMonitor);
+ if (mDelegate) {
+ nsCOMPtr<nsIRunnable> releaser = new nsHtml5StreamParserReleaser(mDelegate);
+ if (NS_FAILED(((nsHtml5StreamParser*)mDelegate)
+ ->DispatchToMain(releaser.forget()))) {
+ NS_WARNING("Failed to dispatch releaser event.");
+ }
+ mDelegate = nullptr;
+ }
+}
+
+nsHtml5StreamParser* nsHtml5StreamListener::GetDelegate() {
+ MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
+ // Since this can be called only on the main
+ // thread and DropDelegate() can only be called on the main thread
+ // it's OK that the monitor here doesn't protect the use of the
+ // return value.
+ return mDelegate;
+}
+
+NS_IMETHODIMP
+nsHtml5StreamListener::CheckListenerChain() {
+ if (MOZ_UNLIKELY(!mDelegate)) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsHtml5StreamListener::OnStartRequest(nsIRequest* aRequest) {
+ mozilla::ReentrantMonitorAutoEnter autoEnter(mDelegateMonitor);
+ if (MOZ_UNLIKELY(!mDelegate)) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+ return ((nsHtml5StreamParser*)mDelegate)->OnStartRequest(aRequest);
+}
+
+NS_IMETHODIMP
+nsHtml5StreamListener::OnStopRequest(nsIRequest* aRequest, nsresult aStatus) {
+ mozilla::ReentrantMonitorAutoEnter autoEnter(mDelegateMonitor);
+ if (MOZ_UNLIKELY(!mDelegate)) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+ return ((nsHtml5StreamParser*)mDelegate)->OnStopRequest(aRequest, aStatus);
+}
+
+NS_IMETHODIMP
+nsHtml5StreamListener::OnDataAvailable(nsIRequest* aRequest,
+ nsIInputStream* aInStream,
+ uint64_t aSourceOffset,
+ uint32_t aLength) {
+ mozilla::ReentrantMonitorAutoEnter autoEnter(mDelegateMonitor);
+ if (MOZ_UNLIKELY(!mDelegate)) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+ return ((nsHtml5StreamParser*)mDelegate)
+ ->OnDataAvailable(aRequest, aInStream, aSourceOffset, aLength);
+}