xpcom/glue/nsWeakReference.cpp

branch
TOR_BUG_3246
changeset 7
129ffea94266
equal deleted inserted replaced
-1:000000000000 0:a534765e5200
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/. */
6
7 // nsWeakReference.cpp
8
9 #include "mozilla/Attributes.h"
10
11 #include "nsWeakReference.h"
12 #include "nsCOMPtr.h"
13
14 class nsWeakReference MOZ_FINAL : public nsIWeakReference
15 {
16 public:
17 // nsISupports...
18 NS_DECL_ISUPPORTS
19
20 // nsIWeakReference...
21 NS_DECL_NSIWEAKREFERENCE
22
23 private:
24 friend class nsSupportsWeakReference;
25
26 nsWeakReference( nsSupportsWeakReference* referent )
27 : mReferent(referent)
28 // ...I can only be constructed by an |nsSupportsWeakReference|
29 {
30 // nothing else to do here
31 }
32
33 ~nsWeakReference()
34 // ...I will only be destroyed by calling |delete| myself.
35 {
36 if ( mReferent )
37 mReferent->NoticeProxyDestruction();
38 }
39
40 void
41 NoticeReferentDestruction()
42 // ...called (only) by an |nsSupportsWeakReference| from _its_ dtor.
43 {
44 mReferent = 0;
45 }
46
47 nsSupportsWeakReference* mReferent;
48 };
49
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;
61
62 if ( mErrorPtr )
63 *mErrorPtr = status;
64 return status;
65 }
66
67 NS_COM_GLUE nsIWeakReference* // or else |already_AddRefed<nsIWeakReference>|
68 NS_GetWeakReference( nsISupports* aInstancePtr, nsresult* aErrorPtr )
69 {
70 nsresult status;
71
72 nsIWeakReference* result = nullptr;
73
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;
85
86 if ( aErrorPtr )
87 *aErrorPtr = status;
88 return result;
89 }
90
91 NS_COM_GLUE nsresult
92 nsSupportsWeakReference::GetWeakReference( nsIWeakReference** aInstancePtr )
93 {
94 if ( !aInstancePtr )
95 return NS_ERROR_NULL_POINTER;
96
97 if ( !mProxy )
98 mProxy = new nsWeakReference(this);
99 *aInstancePtr = mProxy;
100
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 }
109
110 return status;
111 }
112
113 NS_IMPL_ISUPPORTS(nsWeakReference, nsIWeakReference)
114
115 NS_IMETHODIMP
116 nsWeakReference::QueryReferent( const nsIID& aIID, void** aInstancePtr )
117 {
118 return mReferent ? mReferent->QueryInterface(aIID, aInstancePtr) : NS_ERROR_NULL_POINTER;
119 }
120
121 void
122 nsSupportsWeakReference::ClearWeakReferences()
123 {
124 if ( mProxy )
125 {
126 mProxy->NoticeReferentDestruction();
127 mProxy = 0;
128 }
129 }
130

mercurial