Coverage Report

Created: 2018-09-25 14:53

/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