|
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 |