Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/xpcom/tests/gtest/TestAutoRefCnt.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
#include "nsISupportsImpl.h"
8
9
#include "mozilla/Atomics.h"
10
#include "nsThreadUtils.h"
11
12
#include "gtest/gtest.h"
13
14
using namespace mozilla;
15
16
class nsThreadSafeAutoRefCntRunner final : public nsIRunnable
17
{
18
public:
19
  NS_DECL_THREADSAFE_ISUPPORTS
20
21
  NS_IMETHOD Run() final
22
0
  {
23
0
    for (int i = 0; i < 10000; i++) {
24
0
      if (++sRefCnt == 1) {
25
0
        sIncToOne++;
26
0
      }
27
0
      if (--sRefCnt == 0) {
28
0
        sDecToZero++;
29
0
      }
30
0
    }
31
0
    return NS_OK;
32
0
  }
33
34
  static ThreadSafeAutoRefCnt sRefCnt;
35
  static Atomic<uint32_t, Relaxed> sIncToOne;
36
  static Atomic<uint32_t, Relaxed> sDecToZero;
37
38
private:
39
0
  ~nsThreadSafeAutoRefCntRunner() {}
40
};
41
42
NS_IMPL_ISUPPORTS(nsThreadSafeAutoRefCntRunner, nsIRunnable)
43
44
ThreadSafeAutoRefCnt nsThreadSafeAutoRefCntRunner::sRefCnt;
45
Atomic<uint32_t, Relaxed> nsThreadSafeAutoRefCntRunner::sIncToOne(0);
46
Atomic<uint32_t, Relaxed> nsThreadSafeAutoRefCntRunner::sDecToZero(0);
47
48
// When a refcounted object is actually owned by a cache, we may not
49
// want to release the object after last reference gets released. In
50
// this pattern, the cache may rely on the balance of increment to one
51
// and decrement to zero, so that it can maintain a counter for GC.
52
TEST(AutoRefCnt, ThreadSafeAutoRefCntBalance)
53
0
{
54
0
  static const size_t kThreadCount = 4;
55
0
  nsCOMPtr<nsIThread> threads[kThreadCount];
56
0
  for (size_t i = 0; i < kThreadCount; i++) {
57
0
    nsresult rv = NS_NewThread(getter_AddRefs(threads[i]),
58
0
                               new nsThreadSafeAutoRefCntRunner);
59
0
    EXPECT_TRUE(NS_SUCCEEDED(rv));
60
0
  }
61
0
  for (size_t i = 0; i < kThreadCount; i++) {
62
0
    threads[i]->Shutdown();
63
0
  }
64
0
  EXPECT_EQ(nsThreadSafeAutoRefCntRunner::sRefCnt, nsrefcnt(0));
65
0
  EXPECT_EQ(nsThreadSafeAutoRefCntRunner::sIncToOne,
66
0
            nsThreadSafeAutoRefCntRunner::sDecToZero);
67
0
}