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 "nsHtml5RefPtr.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 nsHtml5RefPtr, which releases the object that it points
22  * to from a runnable on the main thread. DropDelegate() is only called on
23  * 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 nsHtml5RefPtr to
29  * prevent it from double-releasing nsHtml5StreamParser.
30  */
31 class nsHtml5StreamListener : public nsIStreamListener,
32                               public nsIThreadRetargetableStreamListener
33 {
34 public:
35   explicit nsHtml5StreamListener(nsHtml5StreamParser* aDelegate);
36 
37   NS_DECL_THREADSAFE_ISUPPORTS
38   NS_DECL_NSIREQUESTOBSERVER
39   NS_DECL_NSISTREAMLISTENER
40   NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
41 
GetDelegate()42   inline nsHtml5StreamParser* GetDelegate()
43   {
44     return mDelegate;
45   }
46 
47   void DropDelegate();
48 
49 private:
50   virtual ~nsHtml5StreamListener();
51 
52   nsHtml5RefPtr<nsHtml5StreamParser> mDelegate;
53 };
54 
55 #endif // nsHtml5StreamListener_h
56