1 /*
2  * Copyright 2012 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "SkRefCnt.h"
9 #include "SkThreadUtils.h"
10 #include "SkTypes.h"
11 #include "SkWeakRefCnt.h"
12 #include "Test.h"
13 
bounce_ref(void * data)14 static void bounce_ref(void* data) {
15     SkRefCnt* ref = static_cast<SkRefCnt*>(data);
16     for (int i = 0; i < 100000; ++i) {
17         ref->ref();
18         ref->unref();
19     }
20 }
21 
test_refCnt(skiatest::Reporter * reporter)22 static void test_refCnt(skiatest::Reporter* reporter) {
23     SkRefCnt* ref = new SkRefCnt();
24 
25     SkThread thing1(bounce_ref, ref);
26     SkThread thing2(bounce_ref, ref);
27 
28     SkASSERT(thing1.start());
29     SkASSERT(thing2.start());
30 
31     thing1.join();
32     thing2.join();
33 
34     REPORTER_ASSERT(reporter, ref->unique());
35     ref->unref();
36 }
37 
bounce_weak_ref(void * data)38 static void bounce_weak_ref(void* data) {
39     SkWeakRefCnt* ref = static_cast<SkWeakRefCnt*>(data);
40     for (int i = 0; i < 100000; ++i) {
41         if (ref->try_ref()) {
42             ref->unref();
43         }
44     }
45 }
46 
bounce_weak_weak_ref(void * data)47 static void bounce_weak_weak_ref(void* data) {
48     SkWeakRefCnt* ref = static_cast<SkWeakRefCnt*>(data);
49     for (int i = 0; i < 100000; ++i) {
50         ref->weak_ref();
51         ref->weak_unref();
52     }
53 }
54 
test_weakRefCnt(skiatest::Reporter * reporter)55 static void test_weakRefCnt(skiatest::Reporter* reporter) {
56     SkWeakRefCnt* ref = new SkWeakRefCnt();
57 
58     SkThread thing1(bounce_ref, ref);
59     SkThread thing2(bounce_ref, ref);
60     SkThread thing3(bounce_weak_ref, ref);
61     SkThread thing4(bounce_weak_weak_ref, ref);
62 
63     SkASSERT(thing1.start());
64     SkASSERT(thing2.start());
65     SkASSERT(thing3.start());
66     SkASSERT(thing4.start());
67 
68     thing1.join();
69     thing2.join();
70     thing3.join();
71     thing4.join();
72 
73     REPORTER_ASSERT(reporter, ref->unique());
74     REPORTER_ASSERT(reporter, ref->getWeakCnt() == 1);
75     ref->unref();
76 }
77 
DEF_TEST(RefCnt,reporter)78 DEF_TEST(RefCnt, reporter) {
79     test_refCnt(reporter);
80     test_weakRefCnt(reporter);
81 }
82