Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(260)

Side by Side Diff: cc/layers/delegated_frame_resource_collection_unittest.cc

Issue 47703005: Fix DelegatedFrameResourceCollection thread safety (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « cc/layers/delegated_frame_resource_collection.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/bind.h"
6 #include "base/run_loop.h"
7 #include "base/synchronization/waitable_event.h"
8 #include "base/threading/thread.h"
9 #include "cc/layers/delegated_frame_resource_collection.h"
10 #include "cc/resources/returned_resource.h"
11 #include "cc/resources/transferable_resource.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13
14 namespace cc {
15 namespace {
16
17 class DelegatedFrameResourceCollectionTest
18 : public testing::Test,
19 public DelegatedFrameResourceCollectionClient {
20 protected:
21 DelegatedFrameResourceCollectionTest() : resources_available_(false) {}
22
23 virtual void SetUp() OVERRIDE { CreateResourceCollection(); }
24
25 virtual void TearDown() OVERRIDE { DestroyResourceCollection(); }
26
27 void CreateResourceCollection() {
28 DCHECK(!resource_collection_);
29 resource_collection_ = new DelegatedFrameResourceCollection;
30 resource_collection_->SetClient(this);
31 }
32
33 void DestroyResourceCollection() {
34 if (resource_collection_) {
35 resource_collection_->SetClient(NULL);
36 resource_collection_ = NULL;
37 }
38 }
39
40 TransferableResourceArray CreateResourceArray() {
41 TransferableResourceArray resources;
42 TransferableResource resource;
43 resource.id = 444;
44 resources.push_back(resource);
45 return resources;
46 }
47
48 virtual void UnusedResourcesAreAvailable() OVERRIDE {
49 resources_available_ = true;
50 resource_collection_->TakeUnusedResourcesForChildCompositor(
51 &returned_resources_);
52 if (!resources_available_closure_.is_null())
53 resources_available_closure_.Run();
54 }
55
56 bool ReturnAndResetResourcesAvailable() {
57 bool r = resources_available_;
58 resources_available_ = false;
59 return r;
60 }
61
62 scoped_refptr<DelegatedFrameResourceCollection> resource_collection_;
63 bool resources_available_;
64 ReturnedResourceArray returned_resources_;
65 base::Closure resources_available_closure_;
66 };
67
68 // This checks that taking the return callback doesn't take extra refcounts,
69 // since it's sent to other threads.
70 TEST_F(DelegatedFrameResourceCollectionTest, NoRef) {
71 // Start with one ref.
72 EXPECT_TRUE(resource_collection_->HasOneRef());
73
74 ReturnCallback return_callback =
75 resource_collection_->GetReturnResourcesCallbackForImplThread();
76
77 // Callback shouldn't take a ref since it's sent to other threads.
78 EXPECT_TRUE(resource_collection_->HasOneRef());
79 }
80
81 void ReturnResourcesOnThread(ReturnCallback callback,
82 const ReturnedResourceArray& resources,
83 base::WaitableEvent* event) {
84 callback.Run(resources);
85 event->Wait();
86 }
87
88 // Tests that the ReturnCallback can run safely on threads even after the
89 // last references to the collection were dropped.
90 TEST_F(DelegatedFrameResourceCollectionTest, Thread) {
91 base::Thread thread("test thread");
92 thread.Start();
93
94 TransferableResourceArray resources = CreateResourceArray();
95 resource_collection_->ReceivedResources(resources);
96 resource_collection_->RefResources(resources);
97
98 ReturnedResourceArray returned_resources;
99 TransferableResource::ReturnResources(resources, &returned_resources);
100
101 base::WaitableEvent event(false, false);
102
103 {
104 base::RunLoop run_loop;
105 resources_available_closure_ = run_loop.QuitClosure();
106
107 thread.message_loop()->PostTask(
108 FROM_HERE,
109 base::Bind(
110 &ReturnResourcesOnThread,
111 resource_collection_->GetReturnResourcesCallbackForImplThread(),
112 returned_resources,
113 &event));
114
115 run_loop.Run();
116 }
117 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
118 EXPECT_EQ(1u, returned_resources_.size());
119 EXPECT_EQ(444u, returned_resources_[0].id);
120 EXPECT_EQ(1, returned_resources_[0].count);
121 returned_resources_.clear();
122
123 // The event prevents the return resources callback from being deleted.
124 // Destroy the last reference from this thread to the collection before
125 // signaling the event, to ensure any reference taken by the callback, if any,
126 // would be the last one.
127 DestroyResourceCollection();
128 event.Signal();
129
130 CreateResourceCollection();
131 resource_collection_->ReceivedResources(resources);
132 resource_collection_->RefResources(resources);
133
134 // Destroy the collection before we have a chance to run the return callback.
135 ReturnCallback return_callback =
136 resource_collection_->GetReturnResourcesCallbackForImplThread();
137 resource_collection_->LoseAllResources();
138 DestroyResourceCollection();
139
140 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
141 EXPECT_EQ(1u, returned_resources_.size());
142 EXPECT_EQ(444u, returned_resources_[0].id);
143 EXPECT_EQ(1, returned_resources_[0].count);
144 EXPECT_TRUE(returned_resources_[0].lost);
145 returned_resources_.clear();
146
147 thread.message_loop()->PostTask(FROM_HERE,
148 base::Bind(&ReturnResourcesOnThread,
149 return_callback,
150 returned_resources,
151 &event));
152 event.Signal();
153
154 thread.Stop();
155 }
156
157 } // namespace
158 } // namespace cc
OLDNEW
« no previous file with comments | « cc/layers/delegated_frame_resource_collection.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698