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

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

Issue 1676913002: [mojo] Delete third_party/mojo (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: let's try that again Created 4 years, 10 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/data_pipe_unittest.cc ('k') | mojo/edk/system/message_pipe_test_utils.h » ('j') | 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 "mojo/edk/system/dispatcher.h"
6
7 #include <stddef.h>
8
9 #include "base/memory/ref_counted.h"
10 #include "base/memory/scoped_vector.h"
11 #include "base/synchronization/waitable_event.h"
12 #include "base/threading/simple_thread.h"
13 #include "mojo/edk/embedder/platform_shared_buffer.h"
14 #include "mojo/edk/system/waiter.h"
15 #include "mojo/public/cpp/system/macros.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17
18 namespace mojo {
19 namespace edk {
20 namespace {
21
22 // Trivial subclass that makes the constructor public.
23 class TrivialDispatcher final : public Dispatcher {
24 public:
25 TrivialDispatcher() {}
26
27 Type GetType() const override { return Type::UNKNOWN; }
28
29 private:
30 friend class base::RefCountedThreadSafe<TrivialDispatcher>;
31 ~TrivialDispatcher() override {}
32
33 scoped_refptr<Dispatcher> CreateEquivalentDispatcherAndCloseImplNoLock()
34 override {
35 lock().AssertAcquired();
36 return scoped_refptr<Dispatcher>(new TrivialDispatcher());
37 }
38
39 MOJO_DISALLOW_COPY_AND_ASSIGN(TrivialDispatcher);
40 };
41
42 TEST(DispatcherTest, Basic) {
43 scoped_refptr<Dispatcher> d(new TrivialDispatcher());
44
45 EXPECT_EQ(Dispatcher::Type::UNKNOWN, d->GetType());
46
47 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
48 d->WriteMessage(nullptr, 0, nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
49 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
50 d->ReadMessage(nullptr, nullptr, nullptr, nullptr,
51 MOJO_WRITE_MESSAGE_FLAG_NONE));
52 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
53 d->WriteData(nullptr, nullptr, MOJO_WRITE_DATA_FLAG_NONE));
54 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
55 d->BeginWriteData(nullptr, nullptr, MOJO_WRITE_DATA_FLAG_NONE));
56 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, d->EndWriteData(0));
57 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
58 d->ReadData(nullptr, nullptr, MOJO_READ_DATA_FLAG_NONE));
59 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
60 d->BeginReadData(nullptr, nullptr, MOJO_READ_DATA_FLAG_NONE));
61 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, d->EndReadData(0));
62 Waiter w;
63 w.Init();
64 HandleSignalsState hss;
65 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
66 d->AddAwakable(&w, ~MOJO_HANDLE_SIGNAL_NONE, 0, &hss));
67 EXPECT_EQ(0u, hss.satisfied_signals);
68 EXPECT_EQ(0u, hss.satisfiable_signals);
69 // Okay to remove even if it wasn't added (or was already removed).
70 hss = HandleSignalsState();
71 d->RemoveAwakable(&w, &hss);
72 EXPECT_EQ(0u, hss.satisfied_signals);
73 EXPECT_EQ(0u, hss.satisfiable_signals);
74 hss = HandleSignalsState();
75 d->RemoveAwakable(&w, &hss);
76 EXPECT_EQ(0u, hss.satisfied_signals);
77 EXPECT_EQ(0u, hss.satisfiable_signals);
78
79 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
80
81 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
82 d->WriteMessage(nullptr, 0, nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE));
83 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
84 d->ReadMessage(nullptr, nullptr, nullptr, nullptr,
85 MOJO_WRITE_MESSAGE_FLAG_NONE));
86 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
87 d->WriteData(nullptr, nullptr, MOJO_WRITE_DATA_FLAG_NONE));
88 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
89 d->BeginWriteData(nullptr, nullptr, MOJO_WRITE_DATA_FLAG_NONE));
90 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, d->EndWriteData(0));
91 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
92 d->ReadData(nullptr, nullptr, MOJO_READ_DATA_FLAG_NONE));
93 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
94 d->BeginReadData(nullptr, nullptr, MOJO_READ_DATA_FLAG_NONE));
95 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, d->EndReadData(0));
96 hss = HandleSignalsState();
97 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
98 d->AddAwakable(&w, ~MOJO_HANDLE_SIGNAL_NONE, 0, &hss));
99 EXPECT_EQ(0u, hss.satisfied_signals);
100 EXPECT_EQ(0u, hss.satisfiable_signals);
101 hss = HandleSignalsState();
102 d->RemoveAwakable(&w, &hss);
103 EXPECT_EQ(0u, hss.satisfied_signals);
104 EXPECT_EQ(0u, hss.satisfiable_signals);
105 }
106
107 class ThreadSafetyStressThread : public base::SimpleThread {
108 public:
109 enum DispatcherOp {
110 CLOSE = 0,
111 WRITE_MESSAGE,
112 READ_MESSAGE,
113 WRITE_DATA,
114 BEGIN_WRITE_DATA,
115 END_WRITE_DATA,
116 READ_DATA,
117 BEGIN_READ_DATA,
118 END_READ_DATA,
119 DUPLICATE_BUFFER_HANDLE,
120 MAP_BUFFER,
121 ADD_WAITER,
122 REMOVE_WAITER,
123 DISPATCHER_OP_COUNT
124 };
125
126 ThreadSafetyStressThread(base::WaitableEvent* event,
127 scoped_refptr<Dispatcher> dispatcher,
128 DispatcherOp op)
129 : base::SimpleThread("thread_safety_stress_thread"),
130 event_(event),
131 dispatcher_(dispatcher),
132 op_(op) {
133 CHECK_LE(0, op_);
134 CHECK_LT(op_, DISPATCHER_OP_COUNT);
135 }
136
137 ~ThreadSafetyStressThread() override { Join(); }
138
139 private:
140 void Run() override {
141 event_->Wait();
142
143 waiter_.Init();
144 switch (op_) {
145 case CLOSE: {
146 MojoResult r = dispatcher_->Close();
147 EXPECT_TRUE(r == MOJO_RESULT_OK || r == MOJO_RESULT_INVALID_ARGUMENT)
148 << "Result: " << r;
149 break;
150 }
151 case WRITE_MESSAGE:
152 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
153 dispatcher_->WriteMessage(nullptr, 0, nullptr,
154 MOJO_WRITE_MESSAGE_FLAG_NONE));
155 break;
156 case READ_MESSAGE:
157 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
158 dispatcher_->ReadMessage(nullptr, nullptr, nullptr, nullptr,
159 MOJO_WRITE_MESSAGE_FLAG_NONE));
160 break;
161 case WRITE_DATA:
162 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
163 dispatcher_->WriteData(nullptr, nullptr,
164 MOJO_WRITE_DATA_FLAG_NONE));
165 break;
166 case BEGIN_WRITE_DATA:
167 EXPECT_EQ(
168 MOJO_RESULT_INVALID_ARGUMENT,
169 dispatcher_->BeginWriteData(nullptr, nullptr,
170 MOJO_WRITE_DATA_FLAG_NONE));
171 break;
172 case END_WRITE_DATA:
173 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, dispatcher_->EndWriteData(0));
174 break;
175 case READ_DATA:
176 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
177 dispatcher_->ReadData(nullptr, nullptr,
178 MOJO_READ_DATA_FLAG_NONE));
179 break;
180 case BEGIN_READ_DATA:
181 EXPECT_EQ(
182 MOJO_RESULT_INVALID_ARGUMENT,
183 dispatcher_->BeginReadData(nullptr, nullptr,
184 MOJO_READ_DATA_FLAG_NONE));
185 break;
186 case END_READ_DATA:
187 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, dispatcher_->EndReadData(0));
188 break;
189 case DUPLICATE_BUFFER_HANDLE: {
190 scoped_refptr<Dispatcher> unused;
191 EXPECT_EQ(
192 MOJO_RESULT_INVALID_ARGUMENT,
193 dispatcher_->DuplicateBufferHandle(nullptr, &unused));
194 break;
195 }
196 case MAP_BUFFER: {
197 scoped_ptr<PlatformSharedBufferMapping> unused;
198 EXPECT_EQ(
199 MOJO_RESULT_INVALID_ARGUMENT,
200 dispatcher_->MapBuffer(0u, 0u, MOJO_MAP_BUFFER_FLAG_NONE, &unused));
201 break;
202 }
203 case ADD_WAITER: {
204 HandleSignalsState hss;
205 MojoResult r = dispatcher_->AddAwakable(
206 &waiter_, ~MOJO_HANDLE_SIGNAL_NONE, 0, &hss);
207 EXPECT_TRUE(r == MOJO_RESULT_FAILED_PRECONDITION ||
208 r == MOJO_RESULT_INVALID_ARGUMENT);
209 EXPECT_EQ(0u, hss.satisfied_signals);
210 EXPECT_EQ(0u, hss.satisfiable_signals);
211 break;
212 }
213 case REMOVE_WAITER: {
214 HandleSignalsState hss;
215 dispatcher_->RemoveAwakable(&waiter_, &hss);
216 EXPECT_EQ(0u, hss.satisfied_signals);
217 EXPECT_EQ(0u, hss.satisfiable_signals);
218 break;
219 }
220 default:
221 NOTREACHED();
222 break;
223 }
224
225 // Always try to remove the waiter, in case we added it.
226 HandleSignalsState hss;
227 dispatcher_->RemoveAwakable(&waiter_, &hss);
228 EXPECT_EQ(0u, hss.satisfied_signals);
229 EXPECT_EQ(0u, hss.satisfiable_signals);
230 }
231
232 base::WaitableEvent* const event_;
233 const scoped_refptr<Dispatcher> dispatcher_;
234 const DispatcherOp op_;
235
236 Waiter waiter_;
237
238 MOJO_DISALLOW_COPY_AND_ASSIGN(ThreadSafetyStressThread);
239 };
240
241 TEST(DispatcherTest, ThreadSafetyStress) {
242 static const size_t kRepeatCount = 20;
243 static const size_t kNumThreads = 100;
244
245 for (size_t i = 0; i < kRepeatCount; i++) {
246 // Manual reset, not initially signalled.
247 base::WaitableEvent event(true, false);
248 scoped_refptr<Dispatcher> d(new TrivialDispatcher());
249
250 {
251 ScopedVector<ThreadSafetyStressThread> threads;
252 for (size_t j = 0; j < kNumThreads; j++) {
253 ThreadSafetyStressThread::DispatcherOp op =
254 static_cast<ThreadSafetyStressThread::DispatcherOp>(
255 (i + j) % ThreadSafetyStressThread::DISPATCHER_OP_COUNT);
256 threads.push_back(new ThreadSafetyStressThread(&event, d, op));
257 threads.back()->Start();
258 }
259 // Kicks off real work on the threads:
260 event.Signal();
261 } // Joins all the threads.
262
263 // One of the threads should already have closed the dispatcher.
264 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, d->Close());
265 }
266 }
267
268 TEST(DispatcherTest, ThreadSafetyStressNoClose) {
269 static const size_t kRepeatCount = 20;
270 static const size_t kNumThreads = 100;
271
272 for (size_t i = 0; i < kRepeatCount; i++) {
273 // Manual reset, not initially signalled.
274 base::WaitableEvent event(true, false);
275 scoped_refptr<Dispatcher> d(new TrivialDispatcher());
276
277 {
278 ScopedVector<ThreadSafetyStressThread> threads;
279 for (size_t j = 0; j < kNumThreads; j++) {
280 ThreadSafetyStressThread::DispatcherOp op =
281 static_cast<ThreadSafetyStressThread::DispatcherOp>(
282 (i + j) % (ThreadSafetyStressThread::DISPATCHER_OP_COUNT - 1) +
283 1);
284 threads.push_back(new ThreadSafetyStressThread(&event, d, op));
285 threads.back()->Start();
286 }
287 // Kicks off real work on the threads:
288 event.Signal();
289 } // Joins all the threads.
290
291 EXPECT_EQ(MOJO_RESULT_OK, d->Close());
292 }
293 }
294
295 } // namespace
296 } // namespace edk
297 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/edk/system/data_pipe_unittest.cc ('k') | mojo/edk/system/message_pipe_test_utils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698