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.
5 #include "mojo/system/dispatcher.h"
7 #include "base/logging.h"
8 #include "mojo/system/constants.h"
9 #include "mojo/system/message_pipe_dispatcher.h"
16 // TODO(vtl): Maybe this should be defined in a test-only file instead.
17 DispatcherTransport
DispatcherTryStartTransport(
18 Dispatcher
* dispatcher
) {
19 return Dispatcher::HandleTableAccess::TryStartTransport(dispatcher
);
24 // Dispatcher ------------------------------------------------------------------
27 DispatcherTransport
Dispatcher::HandleTableAccess::TryStartTransport(
28 Dispatcher
* dispatcher
) {
31 if (!dispatcher
->lock_
.Try())
32 return DispatcherTransport();
34 // We shouldn't race with things that close dispatchers, since closing can
35 // only take place either under |handle_table_lock_| or when the handle is
37 DCHECK(!dispatcher
->is_closed_
);
39 return DispatcherTransport(dispatcher
);
43 void Dispatcher::TransportDataAccess::StartSerialize(
44 Dispatcher
* dispatcher
,
47 size_t* max_platform_handles
) {
49 dispatcher
->StartSerialize(channel
, max_size
, max_platform_handles
);
53 bool Dispatcher::TransportDataAccess::EndSerializeAndClose(
54 Dispatcher
* dispatcher
,
58 std::vector
<embedder::PlatformHandle
>* platform_handles
) {
60 return dispatcher
->EndSerializeAndClose(channel
, destination
, actual_size
,
65 scoped_refptr
<Dispatcher
> Dispatcher::TransportDataAccess::Deserialize(
70 switch (static_cast<int32_t>(type
)) {
72 DVLOG(2) << "Deserializing invalid handle";
73 return scoped_refptr
<Dispatcher
>();
74 case kTypeMessagePipe
:
75 return scoped_refptr
<Dispatcher
>(
76 MessagePipeDispatcher::Deserialize(channel
, source
, size
));
77 case kTypeDataPipeProducer
:
78 case kTypeDataPipeConsumer
:
79 LOG(WARNING
) << "Deserialization of dispatcher type " << type
81 return scoped_refptr
<Dispatcher
>();
83 LOG(WARNING
) << "Unknown dispatcher type " << type
;
84 return scoped_refptr
<Dispatcher
>();
87 MojoResult
Dispatcher::Close() {
88 base::AutoLock
locker(lock_
);
90 return MOJO_RESULT_INVALID_ARGUMENT
;
93 return MOJO_RESULT_OK
;
96 MojoResult
Dispatcher::WriteMessage(
99 std::vector
<DispatcherTransport
>* transports
,
100 MojoWriteMessageFlags flags
) {
101 DCHECK(!transports
|| (transports
->size() > 0 &&
102 transports
->size() < kMaxMessageNumHandles
));
104 base::AutoLock
locker(lock_
);
106 return MOJO_RESULT_INVALID_ARGUMENT
;
108 return WriteMessageImplNoLock(bytes
, num_bytes
, transports
, flags
);
111 MojoResult
Dispatcher::ReadMessage(void* bytes
,
113 DispatcherVector
* dispatchers
,
114 uint32_t* num_dispatchers
,
115 MojoReadMessageFlags flags
) {
116 DCHECK(!num_dispatchers
|| *num_dispatchers
== 0 ||
117 (dispatchers
&& dispatchers
->empty()));
119 base::AutoLock
locker(lock_
);
121 return MOJO_RESULT_INVALID_ARGUMENT
;
123 return ReadMessageImplNoLock(bytes
, num_bytes
, dispatchers
, num_dispatchers
,
127 MojoResult
Dispatcher::WriteData(const void* elements
,
129 MojoWriteDataFlags flags
) {
130 base::AutoLock
locker(lock_
);
132 return MOJO_RESULT_INVALID_ARGUMENT
;
134 return WriteDataImplNoLock(elements
, num_bytes
, flags
);
137 MojoResult
Dispatcher::BeginWriteData(void** buffer
,
138 uint32_t* buffer_num_bytes
,
139 MojoWriteDataFlags flags
) {
140 base::AutoLock
locker(lock_
);
142 return MOJO_RESULT_INVALID_ARGUMENT
;
144 return BeginWriteDataImplNoLock(buffer
, buffer_num_bytes
, flags
);
147 MojoResult
Dispatcher::EndWriteData(uint32_t num_bytes_written
) {
148 base::AutoLock
locker(lock_
);
150 return MOJO_RESULT_INVALID_ARGUMENT
;
152 return EndWriteDataImplNoLock(num_bytes_written
);
155 MojoResult
Dispatcher::ReadData(void* elements
,
157 MojoReadDataFlags flags
) {
158 base::AutoLock
locker(lock_
);
160 return MOJO_RESULT_INVALID_ARGUMENT
;
162 return ReadDataImplNoLock(elements
, num_bytes
, flags
);
165 MojoResult
Dispatcher::BeginReadData(const void** buffer
,
166 uint32_t* buffer_num_bytes
,
167 MojoReadDataFlags flags
) {
168 base::AutoLock
locker(lock_
);
170 return MOJO_RESULT_INVALID_ARGUMENT
;
172 return BeginReadDataImplNoLock(buffer
, buffer_num_bytes
, flags
);
175 MojoResult
Dispatcher::EndReadData(uint32_t num_bytes_read
) {
176 base::AutoLock
locker(lock_
);
178 return MOJO_RESULT_INVALID_ARGUMENT
;
180 return EndReadDataImplNoLock(num_bytes_read
);
183 MojoResult
Dispatcher::DuplicateBufferHandle(
184 const MojoDuplicateBufferHandleOptions
* options
,
185 scoped_refptr
<Dispatcher
>* new_dispatcher
) {
186 base::AutoLock
locker(lock_
);
188 return MOJO_RESULT_INVALID_ARGUMENT
;
190 return DuplicateBufferHandleImplNoLock(options
, new_dispatcher
);
193 MojoResult
Dispatcher::MapBuffer(
196 MojoMapBufferFlags flags
,
197 scoped_ptr
<RawSharedBufferMapping
>* mapping
) {
198 base::AutoLock
locker(lock_
);
200 return MOJO_RESULT_INVALID_ARGUMENT
;
202 return MapBufferImplNoLock(offset
, num_bytes
, flags
, mapping
);
205 MojoResult
Dispatcher::AddWaiter(Waiter
* waiter
,
207 MojoResult wake_result
) {
208 DCHECK_GE(wake_result
, 0);
210 base::AutoLock
locker(lock_
);
212 return MOJO_RESULT_INVALID_ARGUMENT
;
214 return AddWaiterImplNoLock(waiter
, flags
, wake_result
);
217 void Dispatcher::RemoveWaiter(Waiter
* waiter
) {
218 base::AutoLock
locker(lock_
);
221 RemoveWaiterImplNoLock(waiter
);
224 Dispatcher::Dispatcher()
225 : is_closed_(false) {
228 Dispatcher::~Dispatcher() {
229 // Make sure that |Close()| was called.
233 void Dispatcher::CancelAllWaitersNoLock() {
234 lock_
.AssertAcquired();
236 // By default, waiting isn't supported. Only dispatchers that can be waited on
237 // will do something nontrivial.
240 void Dispatcher::CloseImplNoLock() {
241 lock_
.AssertAcquired();
243 // This may not need to do anything. Dispatchers should override this to do
244 // any actual close-time cleanup necessary.
247 MojoResult
Dispatcher::WriteMessageImplNoLock(
248 const void* /*bytes*/,
249 uint32_t /*num_bytes*/,
250 std::vector
<DispatcherTransport
>* /*transports*/,
251 MojoWriteMessageFlags
/*flags*/) {
252 lock_
.AssertAcquired();
254 // By default, not supported. Only needed for message pipe dispatchers.
255 return MOJO_RESULT_INVALID_ARGUMENT
;
258 MojoResult
Dispatcher::ReadMessageImplNoLock(void* /*bytes*/,
259 uint32_t* /*num_bytes*/,
260 DispatcherVector
* /*dispatchers*/,
261 uint32_t* /*num_dispatchers*/,
262 MojoReadMessageFlags
/*flags*/) {
263 lock_
.AssertAcquired();
265 // By default, not supported. Only needed for message pipe dispatchers.
266 return MOJO_RESULT_INVALID_ARGUMENT
;
269 MojoResult
Dispatcher::WriteDataImplNoLock(const void* /*elements*/,
270 uint32_t* /*num_bytes*/,
271 MojoWriteDataFlags
/*flags*/) {
272 lock_
.AssertAcquired();
274 // By default, not supported. Only needed for data pipe dispatchers.
275 return MOJO_RESULT_INVALID_ARGUMENT
;
278 MojoResult
Dispatcher::BeginWriteDataImplNoLock(void** /*buffer*/,
279 uint32_t* /*buffer_num_bytes*/,
280 MojoWriteDataFlags
/*flags*/) {
281 lock_
.AssertAcquired();
283 // By default, not supported. Only needed for data pipe dispatchers.
284 return MOJO_RESULT_INVALID_ARGUMENT
;
287 MojoResult
Dispatcher::EndWriteDataImplNoLock(uint32_t /*num_bytes_written*/) {
288 lock_
.AssertAcquired();
290 // By default, not supported. Only needed for data pipe dispatchers.
291 return MOJO_RESULT_INVALID_ARGUMENT
;
294 MojoResult
Dispatcher::ReadDataImplNoLock(void* /*elements*/,
295 uint32_t* /*num_bytes*/,
296 MojoReadDataFlags
/*flags*/) {
297 lock_
.AssertAcquired();
299 // By default, not supported. Only needed for data pipe dispatchers.
300 return MOJO_RESULT_INVALID_ARGUMENT
;
303 MojoResult
Dispatcher::BeginReadDataImplNoLock(const void** /*buffer*/,
304 uint32_t* /*buffer_num_bytes*/,
305 MojoReadDataFlags
/*flags*/) {
306 lock_
.AssertAcquired();
308 // By default, not supported. Only needed for data pipe dispatchers.
309 return MOJO_RESULT_INVALID_ARGUMENT
;
312 MojoResult
Dispatcher::EndReadDataImplNoLock(uint32_t /*num_bytes_read*/) {
313 lock_
.AssertAcquired();
315 // By default, not supported. Only needed for data pipe dispatchers.
316 return MOJO_RESULT_INVALID_ARGUMENT
;
319 MojoResult
Dispatcher::DuplicateBufferHandleImplNoLock(
320 const MojoDuplicateBufferHandleOptions
* /*options*/,
321 scoped_refptr
<Dispatcher
>* /*new_dispatcher*/) {
322 lock_
.AssertAcquired();
324 // By default, not supported. Only needed for buffer dispatchers.
325 return MOJO_RESULT_INVALID_ARGUMENT
;
328 MojoResult
Dispatcher::MapBufferImplNoLock(
330 uint64_t /*num_bytes*/,
331 MojoMapBufferFlags
/*flags*/,
332 scoped_ptr
<RawSharedBufferMapping
>* /*mapping*/) {
333 lock_
.AssertAcquired();
335 // By default, not supported. Only needed for buffer dispatchers.
336 return MOJO_RESULT_INVALID_ARGUMENT
;
339 MojoResult
Dispatcher::AddWaiterImplNoLock(Waiter
* /*waiter*/,
340 MojoWaitFlags
/*flags*/,
341 MojoResult
/*wake_result*/) {
342 lock_
.AssertAcquired();
344 // By default, waiting isn't supported. Only dispatchers that can be waited on
345 // will do something nontrivial.
346 return MOJO_RESULT_FAILED_PRECONDITION
;
349 void Dispatcher::RemoveWaiterImplNoLock(Waiter
* /*waiter*/) {
350 lock_
.AssertAcquired();
352 // By default, waiting isn't supported. Only dispatchers that can be waited on
353 // will do something nontrivial.
356 void Dispatcher::StartSerializeImplNoLock(Channel
* /*channel*/,
358 size_t* max_platform_handles
) {
359 DCHECK(HasOneRef()); // Only one ref => no need to take the lock.
362 *max_platform_handles
= 0;
365 bool Dispatcher::EndSerializeAndCloseImplNoLock(
366 Channel
* /*channel*/,
367 void* /*destination*/,
368 size_t* /*actual_size*/,
369 std::vector
<embedder::PlatformHandle
>* /*platform_handles*/) {
370 DCHECK(HasOneRef()); // Only one ref => no need to take the lock.
372 // By default, serializing isn't supported, so just close.
377 bool Dispatcher::IsBusyNoLock() const {
378 lock_
.AssertAcquired();
380 // Most dispatchers support only "atomic" operations, so they are never busy
385 void Dispatcher::CloseNoLock() {
386 lock_
.AssertAcquired();
390 CancelAllWaitersNoLock();
394 scoped_refptr
<Dispatcher
>
395 Dispatcher::CreateEquivalentDispatcherAndCloseNoLock() {
396 lock_
.AssertAcquired();
400 CancelAllWaitersNoLock();
401 return CreateEquivalentDispatcherAndCloseImplNoLock();
404 void Dispatcher::StartSerialize(Channel
* channel
,
406 size_t* max_platform_handles
) {
409 DCHECK(max_platform_handles
);
410 DCHECK(HasOneRef()); // Only one ref => no need to take the lock.
412 StartSerializeImplNoLock(channel
, max_size
, max_platform_handles
);
415 bool Dispatcher::EndSerializeAndClose(
419 std::vector
<embedder::PlatformHandle
>* platform_handles
) {
422 DCHECK(HasOneRef()); // Only one ref => no need to take the lock.
425 // Like other |...Close()| methods, we mark ourselves as closed before calling
428 // No need to cancel waiters: we shouldn't have any (and shouldn't be in
429 // |Core|'s handle table.
432 // See the comment above |EndSerializeAndCloseImplNoLock()|. In brief: Locking
433 // isn't actually needed, but we need to satisfy assertions (which we don't
434 // want to remove or weaken).
435 base::AutoLock
locker(lock_
);
438 return EndSerializeAndCloseImplNoLock(channel
, destination
, actual_size
,
442 // DispatcherTransport ---------------------------------------------------------
444 void DispatcherTransport::End() {
446 dispatcher_
->lock_
.Release();
450 } // namespace system