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

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

Issue 814543006: Move //mojo/{public, edk} underneath //third_party (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 5 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
« no previous file with comments | « mojo/edk/system/dispatcher.h ('k') | mojo/edk/system/dispatcher_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
(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 "base/logging.h"
8 #include "mojo/edk/system/configuration.h"
9 #include "mojo/edk/system/message_pipe_dispatcher.h"
10 #include "mojo/edk/system/platform_handle_dispatcher.h"
11 #include "mojo/edk/system/shared_buffer_dispatcher.h"
12
13 namespace mojo {
14 namespace system {
15
16 namespace test {
17
18 // TODO(vtl): Maybe this should be defined in a test-only file instead.
19 DispatcherTransport DispatcherTryStartTransport(Dispatcher* dispatcher) {
20 return Dispatcher::HandleTableAccess::TryStartTransport(dispatcher);
21 }
22
23 } // namespace test
24
25 // Dispatcher ------------------------------------------------------------------
26
27 // static
28 DispatcherTransport Dispatcher::HandleTableAccess::TryStartTransport(
29 Dispatcher* dispatcher) {
30 DCHECK(dispatcher);
31
32 if (!dispatcher->lock_.Try())
33 return DispatcherTransport();
34
35 // We shouldn't race with things that close dispatchers, since closing can
36 // only take place either under |handle_table_lock_| or when the handle is
37 // marked as busy.
38 DCHECK(!dispatcher->is_closed_);
39
40 return DispatcherTransport(dispatcher);
41 }
42
43 // static
44 void Dispatcher::TransportDataAccess::StartSerialize(
45 Dispatcher* dispatcher,
46 Channel* channel,
47 size_t* max_size,
48 size_t* max_platform_handles) {
49 DCHECK(dispatcher);
50 dispatcher->StartSerialize(channel, max_size, max_platform_handles);
51 }
52
53 // static
54 bool Dispatcher::TransportDataAccess::EndSerializeAndClose(
55 Dispatcher* dispatcher,
56 Channel* channel,
57 void* destination,
58 size_t* actual_size,
59 embedder::PlatformHandleVector* platform_handles) {
60 DCHECK(dispatcher);
61 return dispatcher->EndSerializeAndClose(channel, destination, actual_size,
62 platform_handles);
63 }
64
65 // static
66 scoped_refptr<Dispatcher> Dispatcher::TransportDataAccess::Deserialize(
67 Channel* channel,
68 int32_t type,
69 const void* source,
70 size_t size,
71 embedder::PlatformHandleVector* platform_handles) {
72 switch (static_cast<int32_t>(type)) {
73 case kTypeUnknown:
74 DVLOG(2) << "Deserializing invalid handle";
75 return nullptr;
76 case kTypeMessagePipe:
77 return scoped_refptr<Dispatcher>(
78 MessagePipeDispatcher::Deserialize(channel, source, size));
79 case kTypeDataPipeProducer:
80 case kTypeDataPipeConsumer:
81 // TODO(vtl): Implement.
82 LOG(WARNING) << "Deserialization of dispatcher type " << type
83 << " not supported";
84 return nullptr;
85 case kTypeSharedBuffer:
86 return scoped_refptr<Dispatcher>(SharedBufferDispatcher::Deserialize(
87 channel, source, size, platform_handles));
88 case kTypePlatformHandle:
89 return scoped_refptr<Dispatcher>(PlatformHandleDispatcher::Deserialize(
90 channel, source, size, platform_handles));
91 }
92 LOG(WARNING) << "Unknown dispatcher type " << type;
93 return nullptr;
94 }
95
96 MojoResult Dispatcher::Close() {
97 base::AutoLock locker(lock_);
98 if (is_closed_)
99 return MOJO_RESULT_INVALID_ARGUMENT;
100
101 CloseNoLock();
102 return MOJO_RESULT_OK;
103 }
104
105 MojoResult Dispatcher::WriteMessage(
106 UserPointer<const void> bytes,
107 uint32_t num_bytes,
108 std::vector<DispatcherTransport>* transports,
109 MojoWriteMessageFlags flags) {
110 DCHECK(!transports ||
111 (transports->size() > 0 &&
112 transports->size() < GetConfiguration().max_message_num_handles));
113
114 base::AutoLock locker(lock_);
115 if (is_closed_)
116 return MOJO_RESULT_INVALID_ARGUMENT;
117
118 return WriteMessageImplNoLock(bytes, num_bytes, transports, flags);
119 }
120
121 MojoResult Dispatcher::ReadMessage(UserPointer<void> bytes,
122 UserPointer<uint32_t> num_bytes,
123 DispatcherVector* dispatchers,
124 uint32_t* num_dispatchers,
125 MojoReadMessageFlags flags) {
126 DCHECK(!num_dispatchers || *num_dispatchers == 0 ||
127 (dispatchers && dispatchers->empty()));
128
129 base::AutoLock locker(lock_);
130 if (is_closed_)
131 return MOJO_RESULT_INVALID_ARGUMENT;
132
133 return ReadMessageImplNoLock(bytes, num_bytes, dispatchers, num_dispatchers,
134 flags);
135 }
136
137 MojoResult Dispatcher::WriteData(UserPointer<const void> elements,
138 UserPointer<uint32_t> num_bytes,
139 MojoWriteDataFlags flags) {
140 base::AutoLock locker(lock_);
141 if (is_closed_)
142 return MOJO_RESULT_INVALID_ARGUMENT;
143
144 return WriteDataImplNoLock(elements, num_bytes, flags);
145 }
146
147 MojoResult Dispatcher::BeginWriteData(UserPointer<void*> buffer,
148 UserPointer<uint32_t> buffer_num_bytes,
149 MojoWriteDataFlags flags) {
150 base::AutoLock locker(lock_);
151 if (is_closed_)
152 return MOJO_RESULT_INVALID_ARGUMENT;
153
154 return BeginWriteDataImplNoLock(buffer, buffer_num_bytes, flags);
155 }
156
157 MojoResult Dispatcher::EndWriteData(uint32_t num_bytes_written) {
158 base::AutoLock locker(lock_);
159 if (is_closed_)
160 return MOJO_RESULT_INVALID_ARGUMENT;
161
162 return EndWriteDataImplNoLock(num_bytes_written);
163 }
164
165 MojoResult Dispatcher::ReadData(UserPointer<void> elements,
166 UserPointer<uint32_t> num_bytes,
167 MojoReadDataFlags flags) {
168 base::AutoLock locker(lock_);
169 if (is_closed_)
170 return MOJO_RESULT_INVALID_ARGUMENT;
171
172 return ReadDataImplNoLock(elements, num_bytes, flags);
173 }
174
175 MojoResult Dispatcher::BeginReadData(UserPointer<const void*> buffer,
176 UserPointer<uint32_t> buffer_num_bytes,
177 MojoReadDataFlags flags) {
178 base::AutoLock locker(lock_);
179 if (is_closed_)
180 return MOJO_RESULT_INVALID_ARGUMENT;
181
182 return BeginReadDataImplNoLock(buffer, buffer_num_bytes, flags);
183 }
184
185 MojoResult Dispatcher::EndReadData(uint32_t num_bytes_read) {
186 base::AutoLock locker(lock_);
187 if (is_closed_)
188 return MOJO_RESULT_INVALID_ARGUMENT;
189
190 return EndReadDataImplNoLock(num_bytes_read);
191 }
192
193 MojoResult Dispatcher::DuplicateBufferHandle(
194 UserPointer<const MojoDuplicateBufferHandleOptions> options,
195 scoped_refptr<Dispatcher>* new_dispatcher) {
196 base::AutoLock locker(lock_);
197 if (is_closed_)
198 return MOJO_RESULT_INVALID_ARGUMENT;
199
200 return DuplicateBufferHandleImplNoLock(options, new_dispatcher);
201 }
202
203 MojoResult Dispatcher::MapBuffer(
204 uint64_t offset,
205 uint64_t num_bytes,
206 MojoMapBufferFlags flags,
207 scoped_ptr<embedder::PlatformSharedBufferMapping>* mapping) {
208 base::AutoLock locker(lock_);
209 if (is_closed_)
210 return MOJO_RESULT_INVALID_ARGUMENT;
211
212 return MapBufferImplNoLock(offset, num_bytes, flags, mapping);
213 }
214
215 HandleSignalsState Dispatcher::GetHandleSignalsState() const {
216 base::AutoLock locker(lock_);
217 if (is_closed_)
218 return HandleSignalsState();
219
220 return GetHandleSignalsStateImplNoLock();
221 }
222
223 MojoResult Dispatcher::AddAwakable(Awakable* awakable,
224 MojoHandleSignals signals,
225 uint32_t context,
226 HandleSignalsState* signals_state) {
227 base::AutoLock locker(lock_);
228 if (is_closed_) {
229 if (signals_state)
230 *signals_state = HandleSignalsState();
231 return MOJO_RESULT_INVALID_ARGUMENT;
232 }
233
234 return AddAwakableImplNoLock(awakable, signals, context, signals_state);
235 }
236
237 void Dispatcher::RemoveAwakable(Awakable* awakable,
238 HandleSignalsState* handle_signals_state) {
239 base::AutoLock locker(lock_);
240 if (is_closed_) {
241 if (handle_signals_state)
242 *handle_signals_state = HandleSignalsState();
243 return;
244 }
245
246 RemoveAwakableImplNoLock(awakable, handle_signals_state);
247 }
248
249 Dispatcher::Dispatcher() : is_closed_(false) {
250 }
251
252 Dispatcher::~Dispatcher() {
253 // Make sure that |Close()| was called.
254 DCHECK(is_closed_);
255 }
256
257 void Dispatcher::CancelAllAwakablesNoLock() {
258 lock_.AssertAcquired();
259 DCHECK(is_closed_);
260 // By default, waiting isn't supported. Only dispatchers that can be waited on
261 // will do something nontrivial.
262 }
263
264 void Dispatcher::CloseImplNoLock() {
265 lock_.AssertAcquired();
266 DCHECK(is_closed_);
267 // This may not need to do anything. Dispatchers should override this to do
268 // any actual close-time cleanup necessary.
269 }
270
271 MojoResult Dispatcher::WriteMessageImplNoLock(
272 UserPointer<const void> /*bytes*/,
273 uint32_t /*num_bytes*/,
274 std::vector<DispatcherTransport>* /*transports*/,
275 MojoWriteMessageFlags /*flags*/) {
276 lock_.AssertAcquired();
277 DCHECK(!is_closed_);
278 // By default, not supported. Only needed for message pipe dispatchers.
279 return MOJO_RESULT_INVALID_ARGUMENT;
280 }
281
282 MojoResult Dispatcher::ReadMessageImplNoLock(
283 UserPointer<void> /*bytes*/,
284 UserPointer<uint32_t> /*num_bytes*/,
285 DispatcherVector* /*dispatchers*/,
286 uint32_t* /*num_dispatchers*/,
287 MojoReadMessageFlags /*flags*/) {
288 lock_.AssertAcquired();
289 DCHECK(!is_closed_);
290 // By default, not supported. Only needed for message pipe dispatchers.
291 return MOJO_RESULT_INVALID_ARGUMENT;
292 }
293
294 MojoResult Dispatcher::WriteDataImplNoLock(UserPointer<const void> /*elements*/,
295 UserPointer<uint32_t> /*num_bytes*/,
296 MojoWriteDataFlags /*flags*/) {
297 lock_.AssertAcquired();
298 DCHECK(!is_closed_);
299 // By default, not supported. Only needed for data pipe dispatchers.
300 return MOJO_RESULT_INVALID_ARGUMENT;
301 }
302
303 MojoResult Dispatcher::BeginWriteDataImplNoLock(
304 UserPointer<void*> /*buffer*/,
305 UserPointer<uint32_t> /*buffer_num_bytes*/,
306 MojoWriteDataFlags /*flags*/) {
307 lock_.AssertAcquired();
308 DCHECK(!is_closed_);
309 // By default, not supported. Only needed for data pipe dispatchers.
310 return MOJO_RESULT_INVALID_ARGUMENT;
311 }
312
313 MojoResult Dispatcher::EndWriteDataImplNoLock(uint32_t /*num_bytes_written*/) {
314 lock_.AssertAcquired();
315 DCHECK(!is_closed_);
316 // By default, not supported. Only needed for data pipe dispatchers.
317 return MOJO_RESULT_INVALID_ARGUMENT;
318 }
319
320 MojoResult Dispatcher::ReadDataImplNoLock(UserPointer<void> /*elements*/,
321 UserPointer<uint32_t> /*num_bytes*/,
322 MojoReadDataFlags /*flags*/) {
323 lock_.AssertAcquired();
324 DCHECK(!is_closed_);
325 // By default, not supported. Only needed for data pipe dispatchers.
326 return MOJO_RESULT_INVALID_ARGUMENT;
327 }
328
329 MojoResult Dispatcher::BeginReadDataImplNoLock(
330 UserPointer<const void*> /*buffer*/,
331 UserPointer<uint32_t> /*buffer_num_bytes*/,
332 MojoReadDataFlags /*flags*/) {
333 lock_.AssertAcquired();
334 DCHECK(!is_closed_);
335 // By default, not supported. Only needed for data pipe dispatchers.
336 return MOJO_RESULT_INVALID_ARGUMENT;
337 }
338
339 MojoResult Dispatcher::EndReadDataImplNoLock(uint32_t /*num_bytes_read*/) {
340 lock_.AssertAcquired();
341 DCHECK(!is_closed_);
342 // By default, not supported. Only needed for data pipe dispatchers.
343 return MOJO_RESULT_INVALID_ARGUMENT;
344 }
345
346 MojoResult Dispatcher::DuplicateBufferHandleImplNoLock(
347 UserPointer<const MojoDuplicateBufferHandleOptions> /*options*/,
348 scoped_refptr<Dispatcher>* /*new_dispatcher*/) {
349 lock_.AssertAcquired();
350 DCHECK(!is_closed_);
351 // By default, not supported. Only needed for buffer dispatchers.
352 return MOJO_RESULT_INVALID_ARGUMENT;
353 }
354
355 MojoResult Dispatcher::MapBufferImplNoLock(
356 uint64_t /*offset*/,
357 uint64_t /*num_bytes*/,
358 MojoMapBufferFlags /*flags*/,
359 scoped_ptr<embedder::PlatformSharedBufferMapping>* /*mapping*/) {
360 lock_.AssertAcquired();
361 DCHECK(!is_closed_);
362 // By default, not supported. Only needed for buffer dispatchers.
363 return MOJO_RESULT_INVALID_ARGUMENT;
364 }
365
366 HandleSignalsState Dispatcher::GetHandleSignalsStateImplNoLock() const {
367 lock_.AssertAcquired();
368 DCHECK(!is_closed_);
369 // By default, waiting isn't supported. Only dispatchers that can be waited on
370 // will do something nontrivial.
371 return HandleSignalsState();
372 }
373
374 MojoResult Dispatcher::AddAwakableImplNoLock(
375 Awakable* /*awakable*/,
376 MojoHandleSignals /*signals*/,
377 uint32_t /*context*/,
378 HandleSignalsState* signals_state) {
379 lock_.AssertAcquired();
380 DCHECK(!is_closed_);
381 // By default, waiting isn't supported. Only dispatchers that can be waited on
382 // will do something nontrivial.
383 if (signals_state)
384 *signals_state = HandleSignalsState();
385 return MOJO_RESULT_FAILED_PRECONDITION;
386 }
387
388 void Dispatcher::RemoveAwakableImplNoLock(Awakable* /*awakable*/,
389 HandleSignalsState* signals_state) {
390 lock_.AssertAcquired();
391 DCHECK(!is_closed_);
392 // By default, waiting isn't supported. Only dispatchers that can be waited on
393 // will do something nontrivial.
394 if (signals_state)
395 *signals_state = HandleSignalsState();
396 }
397
398 void Dispatcher::StartSerializeImplNoLock(Channel* /*channel*/,
399 size_t* max_size,
400 size_t* max_platform_handles) {
401 DCHECK(HasOneRef()); // Only one ref => no need to take the lock.
402 DCHECK(!is_closed_);
403 *max_size = 0;
404 *max_platform_handles = 0;
405 }
406
407 bool Dispatcher::EndSerializeAndCloseImplNoLock(
408 Channel* /*channel*/,
409 void* /*destination*/,
410 size_t* /*actual_size*/,
411 embedder::PlatformHandleVector* /*platform_handles*/) {
412 DCHECK(HasOneRef()); // Only one ref => no need to take the lock.
413 DCHECK(is_closed_);
414 // By default, serializing isn't supported, so just close.
415 CloseImplNoLock();
416 return false;
417 }
418
419 bool Dispatcher::IsBusyNoLock() const {
420 lock_.AssertAcquired();
421 DCHECK(!is_closed_);
422 // Most dispatchers support only "atomic" operations, so they are never busy
423 // (in this sense).
424 return false;
425 }
426
427 void Dispatcher::CloseNoLock() {
428 lock_.AssertAcquired();
429 DCHECK(!is_closed_);
430
431 is_closed_ = true;
432 CancelAllAwakablesNoLock();
433 CloseImplNoLock();
434 }
435
436 scoped_refptr<Dispatcher>
437 Dispatcher::CreateEquivalentDispatcherAndCloseNoLock() {
438 lock_.AssertAcquired();
439 DCHECK(!is_closed_);
440
441 is_closed_ = true;
442 CancelAllAwakablesNoLock();
443 return CreateEquivalentDispatcherAndCloseImplNoLock();
444 }
445
446 void Dispatcher::StartSerialize(Channel* channel,
447 size_t* max_size,
448 size_t* max_platform_handles) {
449 DCHECK(channel);
450 DCHECK(max_size);
451 DCHECK(max_platform_handles);
452 DCHECK(HasOneRef()); // Only one ref => no need to take the lock.
453 DCHECK(!is_closed_);
454 StartSerializeImplNoLock(channel, max_size, max_platform_handles);
455 }
456
457 bool Dispatcher::EndSerializeAndClose(
458 Channel* channel,
459 void* destination,
460 size_t* actual_size,
461 embedder::PlatformHandleVector* platform_handles) {
462 DCHECK(channel);
463 DCHECK(actual_size);
464 DCHECK(HasOneRef()); // Only one ref => no need to take the lock.
465 DCHECK(!is_closed_);
466
467 // Like other |...Close()| methods, we mark ourselves as closed before calling
468 // the impl. But there's no need to cancel waiters: we shouldn't have any (and
469 // shouldn't be in |Core|'s handle table.
470 is_closed_ = true;
471
472 #if !defined(NDEBUG)
473 // See the comment above |EndSerializeAndCloseImplNoLock()|. In brief: Locking
474 // isn't actually needed, but we need to satisfy assertions (which we don't
475 // want to remove or weaken).
476 base::AutoLock locker(lock_);
477 #endif
478
479 return EndSerializeAndCloseImplNoLock(channel, destination, actual_size,
480 platform_handles);
481 }
482
483 // DispatcherTransport ---------------------------------------------------------
484
485 void DispatcherTransport::End() {
486 DCHECK(dispatcher_);
487 dispatcher_->lock_.Release();
488 dispatcher_ = nullptr;
489 }
490
491 } // namespace system
492 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/edk/system/dispatcher.h ('k') | mojo/edk/system/dispatcher_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698