Bug 1883853 [wpt PR 44937] - [wdspec] fix test_set_permission_origin_unknown, a=testonly
[gecko.git] / mfbt / tests / TestThreadSafeWeakPtr.cpp
blob3670d15bc06ddb95050fa660766a337c8ed62b1f
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> {
16 public:
17 MOZ_DECLARE_REFCOUNTED_TYPENAME(C)
19 int mNum;
21 C() : mNum(0) {}
23 ~C() {
24 // Setting mNum in the destructor allows us to test against use-after-free
25 // below
26 mNum = 0xDEAD;
29 void act() {}
32 // Test that declaring a ThreadSafeWeakPtr pointing to an incomplete type
33 // builds.
34 class Incomplete;
35 class D {
36 ThreadSafeWeakPtr<Incomplete> mMember;
39 int main() {
40 RefPtr<C> c1 = new C;
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);
49 RefPtr<C> s1(w1);
50 // Test a weak pointer for validity before using it.
51 MOZ_RELEASE_ASSERT(s1);
52 MOZ_RELEASE_ASSERT(s1 == c1);
53 s1->mNum = 1;
54 s1->act();
57 // Test taking another ThreadSafeWeakPtr<C> to c1
58 ThreadSafeWeakPtr<C> w2(c1);
60 RefPtr<C> s2(w2);
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
85 RefPtr<C> c2 = new C;
86 c2->mNum = 2;
88 RefPtr<C> s2(w2);
89 MOZ_RELEASE_ASSERT(s2->mNum == 1); // w2 was pointing to c1
91 w2 = c2;
93 RefPtr<C> s2(w2);
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.
103 c1 = nullptr;
105 RefPtr<C> s1(w1);
106 MOZ_RELEASE_ASSERT(
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");
111 RefPtr<C> s2(w2);
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");
119 c2 = nullptr;
121 RefPtr<C> s2(w2);
122 MOZ_RELEASE_ASSERT(
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");