/src/mozilla-central/xpcom/base/nsWeakReference.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |
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 | | #include "nsDebug.h" |
14 | | |
15 | | class nsWeakReference final : public nsIWeakReference |
16 | | { |
17 | | public: |
18 | | // nsISupports... |
19 | | NS_DECL_ISUPPORTS |
20 | | |
21 | | // nsIWeakReference... |
22 | | NS_DECL_NSIWEAKREFERENCE |
23 | | size_t SizeOfOnlyThis(mozilla::MallocSizeOf aMallocSizeOf) const override; |
24 | | |
25 | | private: |
26 | | friend class nsSupportsWeakReference; |
27 | | |
28 | | explicit nsWeakReference(nsSupportsWeakReference* aReferent) |
29 | | : nsIWeakReference(aReferent) |
30 | | // ...I can only be constructed by an |nsSupportsWeakReference| |
31 | 69 | { |
32 | 69 | } |
33 | | |
34 | | ~nsWeakReference() |
35 | | // ...I will only be destroyed by calling |delete| myself. |
36 | 0 | { |
37 | 0 | MOZ_WEAKREF_ASSERT_OWNINGTHREAD; |
38 | 0 | if (mObject) { |
39 | 0 | static_cast<nsSupportsWeakReference*>(mObject)->NoticeProxyDestruction(); |
40 | 0 | } |
41 | 0 | } |
42 | | |
43 | | void |
44 | | NoticeReferentDestruction() |
45 | | // ...called (only) by an |nsSupportsWeakReference| from _its_ dtor. |
46 | 0 | { |
47 | 0 | MOZ_WEAKREF_ASSERT_OWNINGTHREAD; |
48 | 0 | mObject = nullptr; |
49 | 0 | } |
50 | | }; |
51 | | |
52 | | nsresult |
53 | | nsQueryReferent::operator()(const nsIID& aIID, void** aAnswer) const |
54 | 585 | { |
55 | 585 | nsresult status; |
56 | 585 | if (mWeakPtr) { |
57 | 0 | if (NS_FAILED(status = mWeakPtr->QueryReferent(aIID, aAnswer))) { |
58 | 0 | *aAnswer = 0; |
59 | 0 | } |
60 | 585 | } else { |
61 | 585 | status = NS_ERROR_NULL_POINTER; |
62 | 585 | } |
63 | 585 | |
64 | 585 | if (mErrorPtr) { |
65 | 0 | *mErrorPtr = status; |
66 | 0 | } |
67 | 585 | return status; |
68 | 585 | } |
69 | | |
70 | | nsIWeakReference* |
71 | | NS_GetWeakReference(nsISupportsWeakReference* aInstancePtr, nsresult* aErrorPtr) |
72 | 16 | { |
73 | 16 | nsresult status; |
74 | 16 | |
75 | 16 | nsIWeakReference* result = nullptr; |
76 | 16 | |
77 | 16 | if (aInstancePtr) { |
78 | 16 | status = aInstancePtr->GetWeakReference(&result); |
79 | 16 | } else { |
80 | 0 | status = NS_ERROR_NULL_POINTER; |
81 | 0 | } |
82 | 16 | |
83 | 16 | if (aErrorPtr) { |
84 | 0 | *aErrorPtr = status; |
85 | 0 | } |
86 | 16 | |
87 | 16 | return result; |
88 | 16 | } |
89 | | |
90 | | nsIWeakReference* // or else |already_AddRefed<nsIWeakReference>| |
91 | | NS_GetWeakReference(nsISupports* aInstancePtr, nsresult* aErrorPtr) |
92 | 203 | { |
93 | 203 | nsresult status; |
94 | 203 | |
95 | 203 | nsIWeakReference* result = nullptr; |
96 | 203 | |
97 | 203 | if (aInstancePtr) { |
98 | 198 | nsCOMPtr<nsISupportsWeakReference> factoryPtr = |
99 | 198 | do_QueryInterface(aInstancePtr, &status); |
100 | 198 | if (factoryPtr) { |
101 | 189 | status = factoryPtr->GetWeakReference(&result); |
102 | 189 | } |
103 | 198 | // else, |status| has already been set by |do_QueryInterface| |
104 | 198 | } else { |
105 | 5 | status = NS_ERROR_NULL_POINTER; |
106 | 5 | } |
107 | 203 | |
108 | 203 | if (aErrorPtr) { |
109 | 0 | *aErrorPtr = status; |
110 | 0 | } |
111 | 203 | return result; |
112 | 203 | } |
113 | | |
114 | | nsresult |
115 | | nsSupportsWeakReference::GetWeakReference(nsIWeakReference** aInstancePtr) |
116 | 205 | { |
117 | 205 | if (!aInstancePtr) { |
118 | 0 | return NS_ERROR_NULL_POINTER; |
119 | 0 | } |
120 | 205 | |
121 | 205 | if (!mProxy) { |
122 | 69 | mProxy = new nsWeakReference(this); |
123 | 136 | } else { |
124 | 136 | MOZ_WEAKREF_ASSERT_OWNINGTHREAD_DELEGATED(mProxy); |
125 | 136 | } |
126 | 205 | *aInstancePtr = mProxy; |
127 | 205 | |
128 | 205 | nsresult status; |
129 | 205 | if (!*aInstancePtr) { |
130 | 0 | status = NS_ERROR_OUT_OF_MEMORY; |
131 | 205 | } else { |
132 | 205 | NS_ADDREF(*aInstancePtr); |
133 | 205 | status = NS_OK; |
134 | 205 | } |
135 | 205 | |
136 | 205 | return status; |
137 | 205 | } |
138 | | |
139 | | NS_IMPL_ISUPPORTS(nsWeakReference, nsIWeakReference) |
140 | | |
141 | | NS_IMETHODIMP |
142 | | nsWeakReference::QueryReferentFromScript(const nsIID& aIID, void** aInstancePtr) |
143 | 0 | { |
144 | 0 | return QueryReferent(aIID, aInstancePtr); |
145 | 0 | } |
146 | | |
147 | | nsresult |
148 | | nsIWeakReference::QueryReferent(const nsIID& aIID, void** aInstancePtr) |
149 | 1.12M | { |
150 | 1.12M | MOZ_WEAKREF_ASSERT_OWNINGTHREAD; |
151 | 1.12M | |
152 | 1.12M | if (!mObject) { |
153 | 0 | return NS_ERROR_NULL_POINTER; |
154 | 0 | } |
155 | 1.12M | |
156 | 1.12M | return mObject->QueryInterface(aIID, aInstancePtr); |
157 | 1.12M | } |
158 | | |
159 | | size_t |
160 | | nsWeakReference::SizeOfOnlyThis(mozilla::MallocSizeOf aMallocSizeOf) const |
161 | 0 | { |
162 | 0 | return aMallocSizeOf(this); |
163 | 0 | } |
164 | | |
165 | | void |
166 | | nsSupportsWeakReference::ClearWeakReferences() |
167 | 0 | { |
168 | 0 | if (mProxy) { |
169 | 0 | mProxy->NoticeReferentDestruction(); |
170 | 0 | mProxy = nullptr; |
171 | 0 | } |
172 | 0 | } |
173 | | |