Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 // nsWeakReference.cpp
9 #include "mozilla/Attributes.h"
11 #include "nsWeakReference.h"
12 #include "nsCOMPtr.h"
14 class nsWeakReference MOZ_FINAL : public nsIWeakReference
15 {
16 public:
17 // nsISupports...
18 NS_DECL_ISUPPORTS
20 // nsIWeakReference...
21 NS_DECL_NSIWEAKREFERENCE
23 private:
24 friend class nsSupportsWeakReference;
26 nsWeakReference( nsSupportsWeakReference* referent )
27 : mReferent(referent)
28 // ...I can only be constructed by an |nsSupportsWeakReference|
29 {
30 // nothing else to do here
31 }
33 ~nsWeakReference()
34 // ...I will only be destroyed by calling |delete| myself.
35 {
36 if ( mReferent )
37 mReferent->NoticeProxyDestruction();
38 }
40 void
41 NoticeReferentDestruction()
42 // ...called (only) by an |nsSupportsWeakReference| from _its_ dtor.
43 {
44 mReferent = 0;
45 }
47 nsSupportsWeakReference* mReferent;
48 };
50 nsresult
51 nsQueryReferent::operator()( const nsIID& aIID, void** answer ) const
52 {
53 nsresult status;
54 if ( mWeakPtr )
55 {
56 if ( NS_FAILED(status = mWeakPtr->QueryReferent(aIID, answer)) )
57 *answer = 0;
58 }
59 else
60 status = NS_ERROR_NULL_POINTER;
62 if ( mErrorPtr )
63 *mErrorPtr = status;
64 return status;
65 }
67 NS_COM_GLUE nsIWeakReference* // or else |already_AddRefed<nsIWeakReference>|
68 NS_GetWeakReference( nsISupports* aInstancePtr, nsresult* aErrorPtr )
69 {
70 nsresult status;
72 nsIWeakReference* result = nullptr;
74 if ( aInstancePtr )
75 {
76 nsCOMPtr<nsISupportsWeakReference> factoryPtr = do_QueryInterface(aInstancePtr, &status);
77 if ( factoryPtr )
78 {
79 status = factoryPtr->GetWeakReference(&result);
80 }
81 // else, |status| has already been set by |do_QueryInterface|
82 }
83 else
84 status = NS_ERROR_NULL_POINTER;
86 if ( aErrorPtr )
87 *aErrorPtr = status;
88 return result;
89 }
91 NS_COM_GLUE nsresult
92 nsSupportsWeakReference::GetWeakReference( nsIWeakReference** aInstancePtr )
93 {
94 if ( !aInstancePtr )
95 return NS_ERROR_NULL_POINTER;
97 if ( !mProxy )
98 mProxy = new nsWeakReference(this);
99 *aInstancePtr = mProxy;
101 nsresult status;
102 if ( !*aInstancePtr )
103 status = NS_ERROR_OUT_OF_MEMORY;
104 else
105 {
106 NS_ADDREF(*aInstancePtr);
107 status = NS_OK;
108 }
110 return status;
111 }
113 NS_IMPL_ISUPPORTS(nsWeakReference, nsIWeakReference)
115 NS_IMETHODIMP
116 nsWeakReference::QueryReferent( const nsIID& aIID, void** aInstancePtr )
117 {
118 return mReferent ? mReferent->QueryInterface(aIID, aInstancePtr) : NS_ERROR_NULL_POINTER;
119 }
121 void
122 nsSupportsWeakReference::ClearWeakReferences()
123 {
124 if ( mProxy )
125 {
126 mProxy->NoticeReferentDestruction();
127 mProxy = 0;
128 }
129 }