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/. */
7 #include "mozilla/RefPtr.h"
8 #include "mozilla/ThreadSafeWeakPtr.h"
10 using mozilla::SupportsThreadSafeWeakPtr
;
11 using mozilla::ThreadSafeWeakPtr
;
13 // To have a class C support weak pointers, inherit from
14 // SupportsThreadSafeWeakPtr<C>.
15 class C
: public SupportsThreadSafeWeakPtr
<C
> {
17 MOZ_DECLARE_REFCOUNTED_TYPENAME(C
)
24 // Setting mNum in the destructor allows us to test against use-after-free
32 // Test that declaring a ThreadSafeWeakPtr pointing to an incomplete type
36 ThreadSafeWeakPtr
<Incomplete
> mMember
;
41 MOZ_RELEASE_ASSERT(c1
->mNum
== 0);
43 // Get weak pointers to c1. The first time,
44 // a reference-counted ThreadSafeWeakReference object is created that
45 // can live beyond the lifetime of 'c1'. The ThreadSafeWeakReference
46 // object will be notified of 'c1's destruction.
47 ThreadSafeWeakPtr
<C
> w1(c1
);
50 // Test a weak pointer for validity before using it.
51 MOZ_RELEASE_ASSERT(s1
);
52 MOZ_RELEASE_ASSERT(s1
== c1
);
57 // Test taking another ThreadSafeWeakPtr<C> to c1
58 ThreadSafeWeakPtr
<C
> w2(c1
);
61 MOZ_RELEASE_ASSERT(s2
);
62 MOZ_RELEASE_ASSERT(s2
== c1
);
63 MOZ_RELEASE_ASSERT(w1
== s2
);
64 MOZ_RELEASE_ASSERT(s2
->mNum
== 1);
67 // Test that when a ThreadSafeWeakPtr is destroyed, it does not destroy the
68 // object that it points to, and it does not affect other ThreadSafeWeakPtrs
69 // pointing to the same object (e.g. it does not destroy the
70 // ThreadSafeWeakReference object).
72 ThreadSafeWeakPtr
<C
> w4local(c1
);
73 MOZ_RELEASE_ASSERT(w4local
== c1
);
75 // Now w4local has gone out of scope. If that had destroyed c1, then the
76 // following would fail for sure (see C::~C()).
77 MOZ_RELEASE_ASSERT(c1
->mNum
== 1);
78 // Check that w4local going out of scope hasn't affected other
79 // ThreadSafeWeakPtr's pointing to c1
80 MOZ_RELEASE_ASSERT(w1
== c1
);
81 MOZ_RELEASE_ASSERT(w2
== c1
);
83 // Now construct another C object and test changing what object a
84 // ThreadSafeWeakPtr points to
89 MOZ_RELEASE_ASSERT(s2
->mNum
== 1); // w2 was pointing to c1
94 MOZ_RELEASE_ASSERT(s2
);
95 MOZ_RELEASE_ASSERT(s2
== c2
);
96 MOZ_RELEASE_ASSERT(s2
!= c1
);
97 MOZ_RELEASE_ASSERT(w1
!= s2
);
98 MOZ_RELEASE_ASSERT(s2
->mNum
== 2);
101 // Destroying the underlying object clears weak pointers to it.
102 // It should not affect pointers that are not currently pointing to it.
107 !s1
, "Deleting an object should clear ThreadSafeWeakPtr's to it.");
108 MOZ_RELEASE_ASSERT(w1
.IsDead(), "The weak pointer is now dead");
109 MOZ_RELEASE_ASSERT(!w1
.IsNull(), "The weak pointer isn't null");
112 MOZ_RELEASE_ASSERT(s2
,
113 "Deleting an object should not clear ThreadSafeWeakPtr "
114 "that are not pointing to it.");
115 MOZ_RELEASE_ASSERT(!w2
.IsDead(), "The weak pointer isn't dead");
116 MOZ_RELEASE_ASSERT(!w2
.IsNull(), "The weak pointer isn't null");
123 !s2
, "Deleting an object should clear ThreadSafeWeakPtr's to it.");
124 MOZ_RELEASE_ASSERT(w2
.IsDead(), "The weak pointer is now dead");
125 MOZ_RELEASE_ASSERT(!w2
.IsNull(), "The weak pointer isn't null");