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

Side by Side Diff: ppapi/proxy/ppb_var_unittest.cc

Issue 9187055: Reland 9034035: Make it possible to have 1 PpapiGlobals per thread. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 11 months 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 | « ppapi/proxy/ppapi_proxy_test.cc ('k') | ppapi/proxy/ppp_instance_private_proxy_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <string> 5 #include <string>
6 #include <vector> 6 #include <vector>
7 7
8 #include "base/string_number_conversions.h" 8 #include "base/string_number_conversions.h"
9 #include "base/threading/platform_thread.h" 9 #include "base/threading/platform_thread.h"
10 #include "ppapi/c/pp_var.h" 10 #include "ppapi/c/pp_var.h"
11 #include "ppapi/c/ppb_var.h" 11 #include "ppapi/c/ppb_var.h"
12 #include "ppapi/proxy/ppapi_proxy_test.h" 12 #include "ppapi/proxy/ppapi_proxy_test.h"
13 #include "ppapi/shared_impl/ppapi_globals.h"
13 #include "ppapi/shared_impl/ppb_var_shared.h" 14 #include "ppapi/shared_impl/ppb_var_shared.h"
14 15
15 namespace { 16 namespace {
16 std::string VarToString(const PP_Var& var, const PPB_Var* ppb_var) { 17 std::string VarToString(const PP_Var& var, const PPB_Var* ppb_var) {
17 uint32_t len = 0; 18 uint32_t len = 0;
18 const char* utf8 = ppb_var->VarToUtf8(var, &len); 19 const char* utf8 = ppb_var->VarToUtf8(var, &len);
19 return std::string(utf8, len); 20 return std::string(utf8, len);
20 } 21 }
21 const size_t kNumStrings = 100; 22 const size_t kNumStrings = 100;
22 const size_t kNumThreads = 20; 23 const size_t kNumThreads = 20;
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 // 3) Spawn kNumThreads 'RemoveVar' threads. Each of these threads releases each 90 // 3) Spawn kNumThreads 'RemoveVar' threads. Each of these threads releases each
90 // var once. Once all the threads have finished, there should be no vars 91 // var once. Once all the threads have finished, there should be no vars
91 // left. 92 // left.
92 class CreateVarThreadDelegate : public base::PlatformThread::Delegate { 93 class CreateVarThreadDelegate : public base::PlatformThread::Delegate {
93 public: 94 public:
94 // |strings_in|, |vars|, and |strings_out| are arrays, and size is their size. 95 // |strings_in|, |vars|, and |strings_out| are arrays, and size is their size.
95 // For each |strings_in[i]|, we will set |vars[i]| using that value. Then we 96 // For each |strings_in[i]|, we will set |vars[i]| using that value. Then we
96 // read the var back out to |strings_out[i]|. 97 // read the var back out to |strings_out[i]|.
97 CreateVarThreadDelegate(PP_Module pp_module, const std::string* strings_in, 98 CreateVarThreadDelegate(PP_Module pp_module, const std::string* strings_in,
98 PP_Var* vars_out, std::string* strings_out, 99 PP_Var* vars_out, std::string* strings_out,
99 size_t size) 100 size_t size, PpapiGlobals* globals)
100 : pp_module_(pp_module), strings_in_(strings_in), vars_out_(vars_out), 101 : pp_module_(pp_module), strings_in_(strings_in), vars_out_(vars_out),
101 strings_out_(strings_out), size_(size) { 102 strings_out_(strings_out), size_(size), globals_(globals) {
102 } 103 }
103 virtual ~CreateVarThreadDelegate() {} 104 virtual ~CreateVarThreadDelegate() {}
104 virtual void ThreadMain() { 105 virtual void ThreadMain() {
106 PpapiGlobals::SetPpapiGlobalsOnThreadForTest(globals_);
105 const PPB_Var* ppb_var = ppapi::PPB_Var_Shared::GetVarInterface1_1(); 107 const PPB_Var* ppb_var = ppapi::PPB_Var_Shared::GetVarInterface1_1();
106 for (size_t i = 0; i < size_; ++i) { 108 for (size_t i = 0; i < size_; ++i) {
107 vars_out_[i] = ppb_var->VarFromUtf8(strings_in_[i].c_str(), 109 vars_out_[i] = ppb_var->VarFromUtf8(strings_in_[i].c_str(),
108 strings_in_[i].length()); 110 strings_in_[i].length());
109 strings_out_[i] = VarToString(vars_out_[i], ppb_var); 111 strings_out_[i] = VarToString(vars_out_[i], ppb_var);
110 } 112 }
111 } 113 }
112 private: 114 private:
113 PP_Module pp_module_; 115 PP_Module pp_module_;
114 const std::string* strings_in_; 116 const std::string* strings_in_;
115 PP_Var* vars_out_; 117 PP_Var* vars_out_;
116 std::string* strings_out_; 118 std::string* strings_out_;
117 size_t size_; 119 size_t size_;
120 PpapiGlobals* globals_;
118 }; 121 };
119 122
120 // A thread that will increment and decrement the reference count of every var 123 // A thread that will increment and decrement the reference count of every var
121 // multiple times. 124 // multiple times.
122 class ChangeRefVarThreadDelegate : public base::PlatformThread::Delegate { 125 class ChangeRefVarThreadDelegate : public base::PlatformThread::Delegate {
123 public: 126 public:
124 ChangeRefVarThreadDelegate(const std::vector<PP_Var>& vars) : vars_(vars) { 127 ChangeRefVarThreadDelegate(const std::vector<PP_Var>& vars,
128 PpapiGlobals* globals)
129 : vars_(vars), globals_(globals) {
125 } 130 }
126 virtual ~ChangeRefVarThreadDelegate() {} 131 virtual ~ChangeRefVarThreadDelegate() {}
127 virtual void ThreadMain() { 132 virtual void ThreadMain() {
133 PpapiGlobals::SetPpapiGlobalsOnThreadForTest(globals_);
128 const PPB_Var* ppb_var = ppapi::PPB_Var_Shared::GetVarInterface1_1(); 134 const PPB_Var* ppb_var = ppapi::PPB_Var_Shared::GetVarInterface1_1();
129 // Increment and decrement the reference count for each var kRefsToAdd 135 // Increment and decrement the reference count for each var kRefsToAdd
130 // times. Note that we always AddRef once before doing the matching Release, 136 // times. Note that we always AddRef once before doing the matching Release,
131 // to ensure that we never accidentally release the last reference. 137 // to ensure that we never accidentally release the last reference.
132 for (int ref = 0; ref < kRefsToAdd; ++ref) { 138 for (int ref = 0; ref < kRefsToAdd; ++ref) {
133 for (size_t i = 0; i < kNumStrings; ++i) { 139 for (size_t i = 0; i < kNumStrings; ++i) {
134 ppb_var->AddRef(vars_[i]); 140 ppb_var->AddRef(vars_[i]);
135 ppb_var->Release(vars_[i]); 141 ppb_var->Release(vars_[i]);
136 } 142 }
137 } 143 }
138 // Now add 1 ref to each Var. The net result is that all Vars will have a 144 // Now add 1 ref to each Var. The net result is that all Vars will have a
139 // ref-count of (kNumThreads + 1) after this. That will allow us to have all 145 // ref-count of (kNumThreads + 1) after this. That will allow us to have all
140 // threads release all vars later. 146 // threads release all vars later.
141 for (size_t i = 0; i < kNumStrings; ++i) { 147 for (size_t i = 0; i < kNumStrings; ++i) {
142 ppb_var->AddRef(vars_[i]); 148 ppb_var->AddRef(vars_[i]);
143 } 149 }
144 } 150 }
145 private: 151 private:
146 std::vector<PP_Var> vars_; 152 std::vector<PP_Var> vars_;
153 PpapiGlobals* globals_;
147 }; 154 };
148 155
149 // A thread that will decrement the reference count of every var once. 156 // A thread that will decrement the reference count of every var once.
150 class RemoveRefVarThreadDelegate : public base::PlatformThread::Delegate { 157 class RemoveRefVarThreadDelegate : public base::PlatformThread::Delegate {
151 public: 158 public:
152 RemoveRefVarThreadDelegate(const std::vector<PP_Var>& vars) : vars_(vars) { 159 RemoveRefVarThreadDelegate(const std::vector<PP_Var>& vars,
160 PpapiGlobals* globals)
161 : vars_(vars), globals_(globals) {
153 } 162 }
154 virtual ~RemoveRefVarThreadDelegate() {} 163 virtual ~RemoveRefVarThreadDelegate() {}
155 virtual void ThreadMain() { 164 virtual void ThreadMain() {
165 PpapiGlobals::SetPpapiGlobalsOnThreadForTest(globals_);
156 const PPB_Var* ppb_var = ppapi::PPB_Var_Shared::GetVarInterface1_1(); 166 const PPB_Var* ppb_var = ppapi::PPB_Var_Shared::GetVarInterface1_1();
157 for (size_t i = 0; i < kNumStrings; ++i) { 167 for (size_t i = 0; i < kNumStrings; ++i) {
158 ppb_var->Release(vars_[i]); 168 ppb_var->Release(vars_[i]);
159 } 169 }
160 } 170 }
161 private: 171 private:
162 std::vector<PP_Var> vars_; 172 std::vector<PP_Var> vars_;
173 PpapiGlobals* globals_;
163 }; 174 };
164 175
165 } // namespace 176 } // namespace
166 177
167 #ifdef ENABLE_PEPPER_THREADING 178 #ifdef ENABLE_PEPPER_THREADING
168 TEST_F(PPB_VarTest, Threads) { 179 TEST_F(PPB_VarTest, Threads) {
169 #else 180 #else
170 TEST_F(PPB_VarTest, DISABLED_Threads) { 181 TEST_F(PPB_VarTest, DISABLED_Threads) {
171 #endif 182 #endif
172 std::vector<base::PlatformThreadHandle> create_var_threads(kNumThreads); 183 std::vector<base::PlatformThreadHandle> create_var_threads(kNumThreads);
173 std::vector<CreateVarThreadDelegate> create_var_delegates; 184 std::vector<CreateVarThreadDelegate> create_var_delegates;
174 // The strings that the threads will re-extract from Vars (so we can check 185 // The strings that the threads will re-extract from Vars (so we can check
175 // that they match the original strings). 186 // that they match the original strings).
176 std::vector<std::string> strings_out(kNumStrings); 187 std::vector<std::string> strings_out(kNumStrings);
177 size_t strings_per_thread = kNumStrings/kNumThreads; 188 size_t strings_per_thread = kNumStrings/kNumThreads;
178 // Give each thread an equal slice of strings to turn in to vars. (Except the 189 // Give each thread an equal slice of strings to turn in to vars. (Except the
179 // last thread may get fewer if kNumStrings is not evenly divisible by 190 // last thread may get fewer if kNumStrings is not evenly divisible by
180 // kNumThreads). 191 // kNumThreads).
181 for (size_t slice_start= 0; slice_start < kNumStrings; 192 for (size_t slice_start= 0; slice_start < kNumStrings;
182 slice_start += strings_per_thread) { 193 slice_start += strings_per_thread) {
183 create_var_delegates.push_back( 194 create_var_delegates.push_back(
184 CreateVarThreadDelegate(pp_module(), 195 CreateVarThreadDelegate(pp_module(),
185 &test_strings_[slice_start], 196 &test_strings_[slice_start],
186 &vars_[slice_start], 197 &vars_[slice_start],
187 &strings_out[slice_start], 198 &strings_out[slice_start],
188 std::min(strings_per_thread, 199 std::min(strings_per_thread,
189 kNumStrings - slice_start))); 200 kNumStrings - slice_start),
201 GetGlobals()));
190 } 202 }
191 // Now run then join all the threads. 203 // Now run then join all the threads.
192 for (size_t i = 0; i < kNumThreads; ++i) 204 for (size_t i = 0; i < kNumThreads; ++i)
193 base::PlatformThread::Create(0, &create_var_delegates[i], 205 base::PlatformThread::Create(0, &create_var_delegates[i],
194 &create_var_threads[i]); 206 &create_var_threads[i]);
195 for (size_t i = 0; i < kNumThreads; ++i) 207 for (size_t i = 0; i < kNumThreads; ++i)
196 base::PlatformThread::Join(create_var_threads[i]); 208 base::PlatformThread::Join(create_var_threads[i]);
197 // Now check that the strings have the expected values. 209 // Now check that the strings have the expected values.
198 EXPECT_EQ(test_strings_, strings_out); 210 EXPECT_EQ(test_strings_, strings_out);
199 211
200 // Tinker with the reference counts in a multithreaded way. 212 // Tinker with the reference counts in a multithreaded way.
201 std::vector<base::PlatformThreadHandle> change_ref_var_threads(kNumThreads); 213 std::vector<base::PlatformThreadHandle> change_ref_var_threads(kNumThreads);
202 std::vector<ChangeRefVarThreadDelegate> change_ref_var_delegates; 214 std::vector<ChangeRefVarThreadDelegate> change_ref_var_delegates;
203 for (size_t i = 0; i < kNumThreads; ++i) 215 for (size_t i = 0; i < kNumThreads; ++i)
204 change_ref_var_delegates.push_back(ChangeRefVarThreadDelegate(vars_)); 216 change_ref_var_delegates.push_back(
217 ChangeRefVarThreadDelegate(vars_, GetGlobals()));
205 for (size_t i = 0; i < kNumThreads; ++i) { 218 for (size_t i = 0; i < kNumThreads; ++i) {
206 base::PlatformThread::Create(0, &change_ref_var_delegates[i], 219 base::PlatformThread::Create(0, &change_ref_var_delegates[i],
207 &change_ref_var_threads[i]); 220 &change_ref_var_threads[i]);
208 } 221 }
209 for (size_t i = 0; i < kNumThreads; ++i) 222 for (size_t i = 0; i < kNumThreads; ++i)
210 base::PlatformThread::Join(change_ref_var_threads[i]); 223 base::PlatformThread::Join(change_ref_var_threads[i]);
211 224
212 // Now each var has a refcount of (kNumThreads + 1). Let's decrement each var 225 // Now each var has a refcount of (kNumThreads + 1). Let's decrement each var
213 // once so that every 'RemoveRef' thread (spawned below) owns 1 reference, and 226 // once so that every 'RemoveRef' thread (spawned below) owns 1 reference, and
214 // when the last one removes a ref, the Var will be deleted. 227 // when the last one removes a ref, the Var will be deleted.
215 for (size_t i = 0; i < kNumStrings; ++i) { 228 for (size_t i = 0; i < kNumStrings; ++i) {
216 ppb_var_->Release(vars_[i]); 229 ppb_var_->Release(vars_[i]);
217 } 230 }
218 231
219 // Check that all vars are still valid and have the values we expect. 232 // Check that all vars are still valid and have the values we expect.
220 for (size_t i = 0; i < kNumStrings; ++i) 233 for (size_t i = 0; i < kNumStrings; ++i)
221 EXPECT_EQ(test_strings_[i], VarToString(vars_[i], ppb_var_)); 234 EXPECT_EQ(test_strings_[i], VarToString(vars_[i], ppb_var_));
222 235
223 // Remove the last reference counts for all vars. 236 // Remove the last reference counts for all vars.
224 std::vector<base::PlatformThreadHandle> remove_ref_var_threads(kNumThreads); 237 std::vector<base::PlatformThreadHandle> remove_ref_var_threads(kNumThreads);
225 std::vector<RemoveRefVarThreadDelegate> remove_ref_var_delegates; 238 std::vector<RemoveRefVarThreadDelegate> remove_ref_var_delegates;
226 for (size_t i = 0; i < kNumThreads; ++i) 239 for (size_t i = 0; i < kNumThreads; ++i)
227 remove_ref_var_delegates.push_back(RemoveRefVarThreadDelegate(vars_)); 240 remove_ref_var_delegates.push_back(
241 RemoveRefVarThreadDelegate(vars_, GetGlobals()));
228 for (size_t i = 0; i < kNumThreads; ++i) { 242 for (size_t i = 0; i < kNumThreads; ++i) {
229 base::PlatformThread::Create(0, &remove_ref_var_delegates[i], 243 base::PlatformThread::Create(0, &remove_ref_var_delegates[i],
230 &remove_ref_var_threads[i]); 244 &remove_ref_var_threads[i]);
231 } 245 }
232 for (size_t i = 0; i < kNumThreads; ++i) 246 for (size_t i = 0; i < kNumThreads; ++i)
233 base::PlatformThread::Join(remove_ref_var_threads[i]); 247 base::PlatformThread::Join(remove_ref_var_threads[i]);
234 248
235 // All the vars should no longer represent valid strings. 249 // All the vars should no longer represent valid strings.
236 for (size_t i = 0; i < kNumStrings; ++i) { 250 for (size_t i = 0; i < kNumStrings; ++i) {
237 uint32_t len = 10; 251 uint32_t len = 10;
238 const char* utf8 = ppb_var_->VarToUtf8(vars_[i], &len); 252 const char* utf8 = ppb_var_->VarToUtf8(vars_[i], &len);
239 EXPECT_EQ(NULL, utf8); 253 EXPECT_EQ(NULL, utf8);
240 EXPECT_EQ(0u, len); 254 EXPECT_EQ(0u, len);
241 } 255 }
242 } 256 }
243 257
244 } // namespace proxy 258 } // namespace proxy
245 } // namespace ppapi 259 } // namespace ppapi
OLDNEW
« no previous file with comments | « ppapi/proxy/ppapi_proxy_test.cc ('k') | ppapi/proxy/ppp_instance_private_proxy_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698