nsHtml5Module.cpp (3875B)
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 "nsHtml5Module.h" 6 #include "mozilla/AlreadyAddRefed.h" 7 #include "mozilla/Preferences.h" 8 #include "mozilla/Services.h" 9 #include "mozilla/StaticPrefs_html5.h" 10 #include "nsCOMPtr.h" 11 #include "nsHtml5AttributeName.h" 12 #include "nsHtml5ElementName.h" 13 #include "nsHtml5HtmlAttributes.h" 14 #include "nsHtml5NamedCharacters.h" 15 #include "nsHtml5Portability.h" 16 #include "nsHtml5StackNode.h" 17 #include "nsHtml5Tokenizer.h" 18 #include "nsHtml5TreeBuilder.h" 19 #include "nsHtml5UTF16Buffer.h" 20 #include "nsIObserverService.h" 21 22 using namespace mozilla; 23 24 // static 25 nsIThread* nsHtml5Module::sStreamParserThread = nullptr; 26 27 class nsHtml5ParserThreadTerminator final : public nsIObserver { 28 public: 29 NS_DECL_ISUPPORTS 30 explicit nsHtml5ParserThreadTerminator(nsIThread* aThread) 31 : mThread(aThread) {} 32 NS_IMETHOD Observe(nsISupports*, const char* topic, 33 const char16_t*) override { 34 NS_ASSERTION(!strcmp(topic, "xpcom-shutdown-threads"), "Unexpected topic"); 35 mThread->Shutdown(); 36 mThread = nullptr; 37 NS_IF_RELEASE(nsHtml5Module::sStreamParserThread); 38 nsHtml5Module::sStreamParserThread = nullptr; 39 return NS_OK; 40 } 41 42 private: 43 ~nsHtml5ParserThreadTerminator() = default; 44 45 nsCOMPtr<nsIThread> mThread; 46 }; 47 48 NS_IMPL_ISUPPORTS(nsHtml5ParserThreadTerminator, nsIObserver) 49 50 // static 51 void nsHtml5Module::InitializeStatics() { 52 nsHtml5AttributeName::initializeStatics(); 53 nsHtml5ElementName::initializeStatics(); 54 nsHtml5HtmlAttributes::initializeStatics(); 55 nsHtml5NamedCharacters::initializeStatics(); 56 nsHtml5Portability::initializeStatics(); 57 nsHtml5StackNode::initializeStatics(); 58 nsHtml5Tokenizer::initializeStatics(); 59 nsHtml5TreeBuilder::initializeStatics(); 60 nsHtml5UTF16Buffer::initializeStatics(); 61 62 NS_NewNamedThread("HTML5 Parser", &sStreamParserThread); 63 if (sStreamParserThread) { 64 nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService(); 65 if (os) { 66 os->AddObserver(new nsHtml5ParserThreadTerminator(sStreamParserThread), 67 "xpcom-shutdown-threads", false); 68 } else { 69 MOZ_ASSERT(false, 70 "How come we failed to create get the observer service?"); 71 } 72 } else { 73 MOZ_ASSERT(false, "How come we failed to create the parser thread?"); 74 } 75 76 #ifdef DEBUG 77 sNsHtml5ModuleInitialized = true; 78 #endif 79 } 80 81 // static 82 void nsHtml5Module::ReleaseStatics() { 83 #ifdef DEBUG 84 sNsHtml5ModuleInitialized = false; 85 #endif 86 nsHtml5AttributeName::releaseStatics(); 87 nsHtml5ElementName::releaseStatics(); 88 nsHtml5HtmlAttributes::releaseStatics(); 89 nsHtml5NamedCharacters::releaseStatics(); 90 nsHtml5Portability::releaseStatics(); 91 nsHtml5StackNode::releaseStatics(); 92 nsHtml5Tokenizer::releaseStatics(); 93 nsHtml5TreeBuilder::releaseStatics(); 94 nsHtml5UTF16Buffer::releaseStatics(); 95 NS_IF_RELEASE(sStreamParserThread); 96 } 97 98 // static 99 already_AddRefed<nsHtml5Parser> nsHtml5Module::NewHtml5Parser() { 100 MOZ_ASSERT(sNsHtml5ModuleInitialized, "nsHtml5Module not initialized."); 101 RefPtr<nsHtml5Parser> rv = new nsHtml5Parser(); 102 return rv.forget(); 103 } 104 105 // static 106 already_AddRefed<nsISerialEventTarget> 107 nsHtml5Module::GetStreamParserEventTarget() { 108 MOZ_ASSERT(sNsHtml5ModuleInitialized, "nsHtml5Module not initialized."); 109 if (sStreamParserThread) { 110 nsCOMPtr<nsISerialEventTarget> target = sStreamParserThread; 111 return target.forget(); 112 } 113 nsCOMPtr<nsIThread> mainThread; 114 NS_GetMainThread(getter_AddRefs(mainThread)); 115 MOZ_RELEASE_ASSERT(mainThread); // Unrecoverable situation 116 nsCOMPtr<nsISerialEventTarget> target = mainThread; 117 return target.forget(); 118 } 119 120 #ifdef DEBUG 121 bool nsHtml5Module::sNsHtml5ModuleInitialized = false; 122 #endif