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 #ifndef nsHtml5StreamListener_h
6 #define nsHtml5StreamListener_h
7 
8 #include "nsIStreamListener.h"
9 #include "nsIThreadRetargetableStreamListener.h"
10 #include "nsHtml5StreamParserPtr.h"
11 #include "nsHtml5StreamParser.h"
12 
13 /**
14  * The purpose of this class is to reconcile the problem that
15  * nsHtml5StreamParser is a cycle collection participant, which means that it
16  * can only be refcounted on the main thread, but
17  * nsIThreadRetargetableStreamListener can be refcounted from another thread,
18  * so nsHtml5StreamParser being an nsIThreadRetargetableStreamListener was
19  * a memory corruption problem.
20  *
21  * mDelegate is an nsHtml5StreamParserPtr, which releases the object that it
22  * points to from a runnable on the main thread. DropDelegate() is only called
23  * on the main thread. This call will finish before the main-thread derefs the
24  * nsHtml5StreamListener itself, so there is no risk of another thread making
25  * the refcount of nsHtml5StreamListener go to zero and running the destructor
26  * concurrently. Other than that, the thread-safe nsISupports implementation
27  * takes care of the destructor not running concurrently from different
28  * threads, so there is no need to have a mutex around nsHtml5StreamParserPtr to
29  * prevent it from double-releasing nsHtml5StreamParser.
30  */
31 class nsHtml5StreamListener : public nsIStreamListener,
32                               public nsIThreadRetargetableStreamListener {
33  public:
34   explicit nsHtml5StreamListener(nsHtml5StreamParser* aDelegate);
35 
36   NS_DECL_THREADSAFE_ISUPPORTS
37   NS_DECL_NSIREQUESTOBSERVER
38   NS_DECL_NSISTREAMLISTENER
39   NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
40 
GetDelegate()41   inline nsHtml5StreamParser* GetDelegate() { return mDelegate; }
42 
43   void DropDelegate();
44 
45  private:
46   virtual ~nsHtml5StreamListener();
47 
48   nsHtml5StreamParserPtr mDelegate;
49 };
50 
51 #endif  // nsHtml5StreamListener_h
52