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

Side by Side Diff: mojo/edk/system/dispatcher_unittest.cc

Issue 1412283002: Convert mojo::system::Dispatcher to use our new refcounting stuff (instead of base's). (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: no change Created 5 years, 2 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
« no previous file with comments | « mojo/edk/system/dispatcher.cc ('k') | mojo/edk/system/handle_table.h » ('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 2013 The Chromium Authors. All rights reserved. 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 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 "mojo/edk/system/dispatcher.h" 5 #include "mojo/edk/system/dispatcher.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/memory/ref_counted.h"
11 #include "base/synchronization/waitable_event.h" 10 #include "base/synchronization/waitable_event.h"
12 #include "mojo/edk/embedder/platform_shared_buffer.h" 11 #include "mojo/edk/embedder/platform_shared_buffer.h"
13 #include "mojo/edk/system/memory.h" 12 #include "mojo/edk/system/memory.h"
13 #include "mojo/edk/system/ref_ptr.h"
14 #include "mojo/edk/system/waiter.h" 14 #include "mojo/edk/system/waiter.h"
15 #include "mojo/edk/test/simple_test_thread.h" 15 #include "mojo/edk/test/simple_test_thread.h"
16 #include "mojo/edk/util/make_unique.h" 16 #include "mojo/edk/util/make_unique.h"
17 #include "mojo/public/cpp/system/macros.h" 17 #include "mojo/public/cpp/system/macros.h"
18 #include "testing/gtest/include/gtest/gtest.h" 18 #include "testing/gtest/include/gtest/gtest.h"
19 19
20 namespace mojo { 20 namespace mojo {
21 namespace system { 21 namespace system {
22 namespace { 22 namespace {
23 23
24 // Trivial subclass that makes the constructor public. 24 // Trivial subclass that makes the constructor public.
25 class TrivialDispatcher final : public Dispatcher { 25 class TrivialDispatcher final : public Dispatcher {
26 public: 26 public:
27 TrivialDispatcher() {} 27 // Note: Use |MakeRefCounted<TrivialDispatcher>()|.
28 28
29 Type GetType() const override { return Type::UNKNOWN; } 29 Type GetType() const override { return Type::UNKNOWN; }
30 30
31 private: 31 private:
32 FRIEND_MAKE_REF_COUNTED(TrivialDispatcher);
33
34 TrivialDispatcher() {}
32 ~TrivialDispatcher() override {} 35 ~TrivialDispatcher() override {}
33 36
34 scoped_refptr<Dispatcher> CreateEquivalentDispatcherAndCloseImplNoLock() 37 RefPtr<Dispatcher> CreateEquivalentDispatcherAndCloseImplNoLock() override {
35 override {
36 mutex().AssertHeld(); 38 mutex().AssertHeld();
37 return scoped_refptr<Dispatcher>(new TrivialDispatcher()); 39 return AdoptRef(new TrivialDispatcher());
38 } 40 }
39 41
40 MOJO_DISALLOW_COPY_AND_ASSIGN(TrivialDispatcher); 42 MOJO_DISALLOW_COPY_AND_ASSIGN(TrivialDispatcher);
41 }; 43 };
42 44
43 TEST(DispatcherTest, Basic) { 45 TEST(DispatcherTest, Basic) {
44 scoped_refptr<Dispatcher> d(new TrivialDispatcher()); 46 auto d = MakeRefCounted<TrivialDispatcher>();
45 47
46 EXPECT_EQ(Dispatcher::Type::UNKNOWN, d->GetType()); 48 EXPECT_EQ(Dispatcher::Type::UNKNOWN, d->GetType());
47 49
48 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, 50 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
49 d->WriteMessage(NullUserPointer(), 0, nullptr, 51 d->WriteMessage(NullUserPointer(), 0, nullptr,
50 MOJO_WRITE_MESSAGE_FLAG_NONE)); 52 MOJO_WRITE_MESSAGE_FLAG_NONE));
51 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, 53 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
52 d->ReadMessage(NullUserPointer(), NullUserPointer(), nullptr, 54 d->ReadMessage(NullUserPointer(), NullUserPointer(), nullptr,
53 nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE)); 55 nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
54 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, 56 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 BEGIN_READ_DATA, 130 BEGIN_READ_DATA,
129 END_READ_DATA, 131 END_READ_DATA,
130 DUPLICATE_BUFFER_HANDLE, 132 DUPLICATE_BUFFER_HANDLE,
131 MAP_BUFFER, 133 MAP_BUFFER,
132 ADD_WAITER, 134 ADD_WAITER,
133 REMOVE_WAITER, 135 REMOVE_WAITER,
134 DISPATCHER_OP_COUNT 136 DISPATCHER_OP_COUNT
135 }; 137 };
136 138
137 ThreadSafetyStressThread(base::WaitableEvent* event, 139 ThreadSafetyStressThread(base::WaitableEvent* event,
138 scoped_refptr<Dispatcher> dispatcher, 140 RefPtr<Dispatcher> dispatcher,
139 DispatcherOp op) 141 DispatcherOp op)
140 : event_(event), dispatcher_(dispatcher), op_(op) { 142 : event_(event), dispatcher_(dispatcher), op_(op) {
141 CHECK_LE(0, op_); 143 CHECK_LE(0, op_);
142 CHECK_LT(op_, DISPATCHER_OP_COUNT); 144 CHECK_LT(op_, DISPATCHER_OP_COUNT);
143 } 145 }
144 146
145 ~ThreadSafetyStressThread() override { Join(); } 147 ~ThreadSafetyStressThread() override { Join(); }
146 148
147 private: 149 private:
148 void Run() override { 150 void Run() override {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 case BEGIN_READ_DATA: 191 case BEGIN_READ_DATA:
190 EXPECT_EQ( 192 EXPECT_EQ(
191 MOJO_RESULT_INVALID_ARGUMENT, 193 MOJO_RESULT_INVALID_ARGUMENT,
192 dispatcher_->BeginReadData(NullUserPointer(), NullUserPointer(), 194 dispatcher_->BeginReadData(NullUserPointer(), NullUserPointer(),
193 MOJO_READ_DATA_FLAG_NONE)); 195 MOJO_READ_DATA_FLAG_NONE));
194 break; 196 break;
195 case END_READ_DATA: 197 case END_READ_DATA:
196 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, dispatcher_->EndReadData(0)); 198 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, dispatcher_->EndReadData(0));
197 break; 199 break;
198 case DUPLICATE_BUFFER_HANDLE: { 200 case DUPLICATE_BUFFER_HANDLE: {
199 scoped_refptr<Dispatcher> unused; 201 RefPtr<Dispatcher> unused;
200 EXPECT_EQ( 202 EXPECT_EQ(
201 MOJO_RESULT_INVALID_ARGUMENT, 203 MOJO_RESULT_INVALID_ARGUMENT,
202 dispatcher_->DuplicateBufferHandle(NullUserPointer(), &unused)); 204 dispatcher_->DuplicateBufferHandle(NullUserPointer(), &unused));
203 break; 205 break;
204 } 206 }
205 case MAP_BUFFER: { 207 case MAP_BUFFER: {
206 std::unique_ptr<embedder::PlatformSharedBufferMapping> unused; 208 std::unique_ptr<embedder::PlatformSharedBufferMapping> unused;
207 EXPECT_EQ( 209 EXPECT_EQ(
208 MOJO_RESULT_INVALID_ARGUMENT, 210 MOJO_RESULT_INVALID_ARGUMENT,
209 dispatcher_->MapBuffer(0u, 0u, MOJO_MAP_BUFFER_FLAG_NONE, &unused)); 211 dispatcher_->MapBuffer(0u, 0u, MOJO_MAP_BUFFER_FLAG_NONE, &unused));
(...skipping 22 matching lines...) Expand all
232 } 234 }
233 235
234 // Always try to remove the waiter, in case we added it. 236 // Always try to remove the waiter, in case we added it.
235 HandleSignalsState hss; 237 HandleSignalsState hss;
236 dispatcher_->RemoveAwakable(&waiter_, &hss); 238 dispatcher_->RemoveAwakable(&waiter_, &hss);
237 EXPECT_EQ(0u, hss.satisfied_signals); 239 EXPECT_EQ(0u, hss.satisfied_signals);
238 EXPECT_EQ(0u, hss.satisfiable_signals); 240 EXPECT_EQ(0u, hss.satisfiable_signals);
239 } 241 }
240 242
241 base::WaitableEvent* const event_; 243 base::WaitableEvent* const event_;
242 const scoped_refptr<Dispatcher> dispatcher_; 244 const RefPtr<Dispatcher> dispatcher_;
243 const DispatcherOp op_; 245 const DispatcherOp op_;
244 246
245 Waiter waiter_; 247 Waiter waiter_;
246 248
247 MOJO_DISALLOW_COPY_AND_ASSIGN(ThreadSafetyStressThread); 249 MOJO_DISALLOW_COPY_AND_ASSIGN(ThreadSafetyStressThread);
248 }; 250 };
249 251
250 TEST(DispatcherTest, ThreadSafetyStress) { 252 TEST(DispatcherTest, ThreadSafetyStress) {
251 static const size_t kRepeatCount = 20; 253 static const size_t kRepeatCount = 20;
252 static const size_t kNumThreads = 100; 254 static const size_t kNumThreads = 100;
253 255
254 for (size_t i = 0; i < kRepeatCount; i++) { 256 for (size_t i = 0; i < kRepeatCount; i++) {
255 // Manual reset, not initially signalled. 257 // Manual reset, not initially signalled.
256 base::WaitableEvent event(true, false); 258 base::WaitableEvent event(true, false);
257 scoped_refptr<Dispatcher> d(new TrivialDispatcher()); 259 auto d = MakeRefCounted<TrivialDispatcher>();
258 260
259 { 261 {
260 std::vector<std::unique_ptr<ThreadSafetyStressThread>> threads; 262 std::vector<std::unique_ptr<ThreadSafetyStressThread>> threads;
261 for (size_t j = 0; j < kNumThreads; j++) { 263 for (size_t j = 0; j < kNumThreads; j++) {
262 ThreadSafetyStressThread::DispatcherOp op = 264 ThreadSafetyStressThread::DispatcherOp op =
263 static_cast<ThreadSafetyStressThread::DispatcherOp>( 265 static_cast<ThreadSafetyStressThread::DispatcherOp>(
264 (i + j) % ThreadSafetyStressThread::DISPATCHER_OP_COUNT); 266 (i + j) % ThreadSafetyStressThread::DISPATCHER_OP_COUNT);
265 threads.push_back( 267 threads.push_back(
266 util::MakeUnique<ThreadSafetyStressThread>(&event, d, op)); 268 util::MakeUnique<ThreadSafetyStressThread>(&event, d, op));
267 threads.back()->Start(); 269 threads.back()->Start();
268 } 270 }
269 // Kicks off real work on the threads: 271 // Kicks off real work on the threads:
270 event.Signal(); 272 event.Signal();
271 } // Joins all the threads. 273 } // Joins all the threads.
272 274
273 // One of the threads should already have closed the dispatcher. 275 // One of the threads should already have closed the dispatcher.
274 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, d->Close()); 276 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, d->Close());
275 } 277 }
276 } 278 }
277 279
278 TEST(DispatcherTest, ThreadSafetyStressNoClose) { 280 TEST(DispatcherTest, ThreadSafetyStressNoClose) {
279 static const size_t kRepeatCount = 20; 281 static const size_t kRepeatCount = 20;
280 static const size_t kNumThreads = 100; 282 static const size_t kNumThreads = 100;
281 283
282 for (size_t i = 0; i < kRepeatCount; i++) { 284 for (size_t i = 0; i < kRepeatCount; i++) {
283 // Manual reset, not initially signalled. 285 // Manual reset, not initially signalled.
284 base::WaitableEvent event(true, false); 286 base::WaitableEvent event(true, false);
285 scoped_refptr<Dispatcher> d(new TrivialDispatcher()); 287 auto d = MakeRefCounted<TrivialDispatcher>();
286 288
287 { 289 {
288 std::vector<std::unique_ptr<ThreadSafetyStressThread>> threads; 290 std::vector<std::unique_ptr<ThreadSafetyStressThread>> threads;
289 for (size_t j = 0; j < kNumThreads; j++) { 291 for (size_t j = 0; j < kNumThreads; j++) {
290 ThreadSafetyStressThread::DispatcherOp op = 292 ThreadSafetyStressThread::DispatcherOp op =
291 static_cast<ThreadSafetyStressThread::DispatcherOp>( 293 static_cast<ThreadSafetyStressThread::DispatcherOp>(
292 (i + j) % (ThreadSafetyStressThread::DISPATCHER_OP_COUNT - 1) + 294 (i + j) % (ThreadSafetyStressThread::DISPATCHER_OP_COUNT - 1) +
293 1); 295 1);
294 threads.push_back( 296 threads.push_back(
295 util::MakeUnique<ThreadSafetyStressThread>(&event, d, op)); 297 util::MakeUnique<ThreadSafetyStressThread>(&event, d, op));
296 threads.back()->Start(); 298 threads.back()->Start();
297 } 299 }
298 // Kicks off real work on the threads: 300 // Kicks off real work on the threads:
299 event.Signal(); 301 event.Signal();
300 } // Joins all the threads. 302 } // Joins all the threads.
301 303
302 EXPECT_EQ(MOJO_RESULT_OK, d->Close()); 304 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
303 } 305 }
304 } 306 }
305 307
306 } // namespace 308 } // namespace
307 } // namespace system 309 } // namespace system
308 } // namespace mojo 310 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/edk/system/dispatcher.cc ('k') | mojo/edk/system/handle_table.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698