14e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
24e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
34e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// found in the LICENSE file.
44e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
54e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "mojo/system/dispatcher.h"
64e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/logging.h"
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "mojo/system/constants.h"
9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "mojo/system/message_pipe_dispatcher.h"
10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "mojo/system/platform_handle_dispatcher.h"
11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "mojo/system/shared_buffer_dispatcher.h"
124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace mojo {
144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace system {
154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace test {
17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// TODO(vtl): Maybe this should be defined in a test-only file instead.
195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)DispatcherTransport DispatcherTryStartTransport(Dispatcher* dispatcher) {
204ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch  return Dispatcher::HandleTableAccess::TryStartTransport(dispatcher);
21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}  // namespace test
24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Dispatcher ------------------------------------------------------------------
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static
284ad1aa43a48567659193a298fad74f55e00b3dd9Ben MurdochDispatcherTransport Dispatcher::HandleTableAccess::TryStartTransport(
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    Dispatcher* dispatcher) {
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(dispatcher);
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!dispatcher->lock_.Try())
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return DispatcherTransport();
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // We shouldn't race with things that close dispatchers, since closing can
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // only take place either under |handle_table_lock_| or when the handle is
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // marked as busy.
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!dispatcher->is_closed_);
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return DispatcherTransport(dispatcher);
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// static
44010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void Dispatcher::TransportDataAccess::StartSerialize(
45c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    Dispatcher* dispatcher,
46c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    Channel* channel,
47c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    size_t* max_size,
48c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    size_t* max_platform_handles) {
49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(dispatcher);
50c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  dispatcher->StartSerialize(channel, max_size, max_platform_handles);
51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// static
54010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool Dispatcher::TransportDataAccess::EndSerializeAndClose(
55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    Dispatcher* dispatcher,
56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    Channel* channel,
57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    void* destination,
58c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    size_t* actual_size,
59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    embedder::PlatformHandleVector* platform_handles) {
60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(dispatcher);
615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return dispatcher->EndSerializeAndClose(
625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      channel, destination, actual_size, platform_handles);
63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// static
66010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)scoped_refptr<Dispatcher> Dispatcher::TransportDataAccess::Deserialize(
67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    Channel* channel,
68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    int32_t type,
69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const void* source,
70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    size_t size,
71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    embedder::PlatformHandleVector* platform_handles) {
72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  switch (static_cast<int32_t>(type)) {
73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    case kTypeUnknown:
74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      DVLOG(2) << "Deserializing invalid handle";
75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return scoped_refptr<Dispatcher>();
76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    case kTypeMessagePipe:
77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return scoped_refptr<Dispatcher>(
78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          MessagePipeDispatcher::Deserialize(channel, source, size));
79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    case kTypeDataPipeProducer:
80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    case kTypeDataPipeConsumer:
81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // TODO(vtl): Implement.
82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      LOG(WARNING) << "Deserialization of dispatcher type " << type
83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                   << " not supported";
84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return scoped_refptr<Dispatcher>();
85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case kTypeSharedBuffer:
865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return scoped_refptr<Dispatcher>(SharedBufferDispatcher::Deserialize(
875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          channel, source, size, platform_handles));
88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case kTypePlatformHandle:
895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return scoped_refptr<Dispatcher>(PlatformHandleDispatcher::Deserialize(
905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          channel, source, size, platform_handles));
91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  LOG(WARNING) << "Unknown dispatcher type " << type;
93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return scoped_refptr<Dispatcher>();
94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)MojoResult Dispatcher::Close() {
974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::AutoLock locker(lock_);
984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (is_closed_)
994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return MOJO_RESULT_INVALID_ARGUMENT;
1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CloseNoLock();
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return MOJO_RESULT_OK;
1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)MojoResult Dispatcher::WriteMessage(
1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    UserPointer<const void> bytes,
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    uint32_t num_bytes,
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::vector<DispatcherTransport>* transports,
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MojoWriteMessageFlags flags) {
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!transports || (transports->size() > 0 &&
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         transports->size() < kMaxMessageNumHandles));
112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::AutoLock locker(lock_);
1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (is_closed_)
1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return MOJO_RESULT_INVALID_ARGUMENT;
1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return WriteMessageImplNoLock(bytes, num_bytes, transports, flags);
1184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)MojoResult Dispatcher::ReadMessage(UserPointer<void> bytes,
1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                   UserPointer<uint32_t> num_bytes,
122010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                   DispatcherVector* dispatchers,
123010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                   uint32_t* num_dispatchers,
1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                   MojoReadMessageFlags flags) {
125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(!num_dispatchers || *num_dispatchers == 0 ||
126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)         (dispatchers && dispatchers->empty()));
127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::AutoLock locker(lock_);
1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (is_closed_)
1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return MOJO_RESULT_INVALID_ARGUMENT;
1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return ReadMessageImplNoLock(
1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      bytes, num_bytes, dispatchers, num_dispatchers, flags);
1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)MojoResult Dispatcher::WriteData(UserPointer<const void> elements,
1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                 UserPointer<uint32_t> num_bytes,
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                 MojoWriteDataFlags flags) {
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::AutoLock locker(lock_);
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (is_closed_)
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return MOJO_RESULT_INVALID_ARGUMENT;
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return WriteDataImplNoLock(elements, num_bytes, flags);
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)MojoResult Dispatcher::BeginWriteData(UserPointer<void*> buffer,
1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                      UserPointer<uint32_t> buffer_num_bytes,
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      MojoWriteDataFlags flags) {
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::AutoLock locker(lock_);
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (is_closed_)
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return MOJO_RESULT_INVALID_ARGUMENT;
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return BeginWriteDataImplNoLock(buffer, buffer_num_bytes, flags);
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)MojoResult Dispatcher::EndWriteData(uint32_t num_bytes_written) {
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::AutoLock locker(lock_);
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (is_closed_)
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return MOJO_RESULT_INVALID_ARGUMENT;
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return EndWriteDataImplNoLock(num_bytes_written);
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)MojoResult Dispatcher::ReadData(UserPointer<void> elements,
1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                UserPointer<uint32_t> num_bytes,
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                MojoReadDataFlags flags) {
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::AutoLock locker(lock_);
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (is_closed_)
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return MOJO_RESULT_INVALID_ARGUMENT;
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return ReadDataImplNoLock(elements, num_bytes, flags);
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)MojoResult Dispatcher::BeginReadData(UserPointer<const void*> buffer,
1755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                     UserPointer<uint32_t> buffer_num_bytes,
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                     MojoReadDataFlags flags) {
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::AutoLock locker(lock_);
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (is_closed_)
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return MOJO_RESULT_INVALID_ARGUMENT;
1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return BeginReadDataImplNoLock(buffer, buffer_num_bytes, flags);
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)MojoResult Dispatcher::EndReadData(uint32_t num_bytes_read) {
1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::AutoLock locker(lock_);
1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (is_closed_)
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return MOJO_RESULT_INVALID_ARGUMENT;
1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return EndReadDataImplNoLock(num_bytes_read);
1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)MojoResult Dispatcher::DuplicateBufferHandle(
1935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    UserPointer<const MojoDuplicateBufferHandleOptions> options,
194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    scoped_refptr<Dispatcher>* new_dispatcher) {
195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::AutoLock locker(lock_);
196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (is_closed_)
197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return MOJO_RESULT_INVALID_ARGUMENT;
198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return DuplicateBufferHandleImplNoLock(options, new_dispatcher);
200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)MojoResult Dispatcher::MapBuffer(
2036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    uint64_t offset,
2046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    uint64_t num_bytes,
2056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    MojoMapBufferFlags flags,
2066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    scoped_ptr<embedder::PlatformSharedBufferMapping>* mapping) {
207a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::AutoLock locker(lock_);
208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (is_closed_)
209a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return MOJO_RESULT_INVALID_ARGUMENT;
210a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
211effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  return MapBufferImplNoLock(offset, num_bytes, flags, mapping);
212a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
213a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)HandleSignalsState Dispatcher::GetHandleSignalsState() const {
2155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::AutoLock locker(lock_);
2165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (is_closed_)
2175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return HandleSignalsState();
2185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return GetHandleSignalsStateImplNoLock();
2205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)MojoResult Dispatcher::AddWaiter(Waiter* waiter,
223f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                 MojoHandleSignals signals,
2245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                 uint32_t context,
2255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                 HandleSignalsState* signals_state) {
2264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::AutoLock locker(lock_);
2275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (is_closed_) {
2285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (signals_state)
2295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      *signals_state = HandleSignalsState();
2304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return MOJO_RESULT_INVALID_ARGUMENT;
2315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return AddWaiterImplNoLock(waiter, signals, context, signals_state);
2344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void Dispatcher::RemoveWaiter(Waiter* waiter,
2375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              HandleSignalsState* handle_signals_state) {
2384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::AutoLock locker(lock_);
2395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (is_closed_) {
2405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (handle_signals_state)
2415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      *handle_signals_state = HandleSignalsState();
2424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
2435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  RemoveWaiterImplNoLock(waiter, handle_signals_state);
2454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)Dispatcher::Dispatcher() : is_closed_(false) {
2484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)Dispatcher::~Dispatcher() {
2514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Make sure that |Close()| was called.
2524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(is_closed_);
2534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void Dispatcher::CancelAllWaitersNoLock() {
2564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  lock_.AssertAcquired();
2574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(is_closed_);
2584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // By default, waiting isn't supported. Only dispatchers that can be waited on
2594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // will do something nontrivial.
2604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void Dispatcher::CloseImplNoLock() {
2634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  lock_.AssertAcquired();
2644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(is_closed_);
2654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // This may not need to do anything. Dispatchers should override this to do
2664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // any actual close-time cleanup necessary.
2674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)MojoResult Dispatcher::WriteMessageImplNoLock(
2705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    UserPointer<const void> /*bytes*/,
2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    uint32_t /*num_bytes*/,
2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::vector<DispatcherTransport>* /*transports*/,
2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MojoWriteMessageFlags /*flags*/) {
2744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  lock_.AssertAcquired();
2754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(!is_closed_);
2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // By default, not supported. Only needed for message pipe dispatchers.
2774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return MOJO_RESULT_INVALID_ARGUMENT;
2784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)MojoResult Dispatcher::ReadMessageImplNoLock(
2815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    UserPointer<void> /*bytes*/,
2825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    UserPointer<uint32_t> /*num_bytes*/,
2835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    DispatcherVector* /*dispatchers*/,
2845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    uint32_t* /*num_dispatchers*/,
2855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    MojoReadMessageFlags /*flags*/) {
2864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  lock_.AssertAcquired();
2874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(!is_closed_);
2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // By default, not supported. Only needed for message pipe dispatchers.
2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return MOJO_RESULT_INVALID_ARGUMENT;
2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)MojoResult Dispatcher::WriteDataImplNoLock(UserPointer<const void> /*elements*/,
2935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                           UserPointer<uint32_t> /*num_bytes*/,
2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           MojoWriteDataFlags /*flags*/) {
2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  lock_.AssertAcquired();
2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!is_closed_);
2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // By default, not supported. Only needed for data pipe dispatchers.
2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return MOJO_RESULT_INVALID_ARGUMENT;
2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)MojoResult Dispatcher::BeginWriteDataImplNoLock(
3025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    UserPointer<void*> /*buffer*/,
3035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    UserPointer<uint32_t> /*buffer_num_bytes*/,
3045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    MojoWriteDataFlags /*flags*/) {
3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  lock_.AssertAcquired();
3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!is_closed_);
3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // By default, not supported. Only needed for data pipe dispatchers.
3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return MOJO_RESULT_INVALID_ARGUMENT;
3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)MojoResult Dispatcher::EndWriteDataImplNoLock(uint32_t /*num_bytes_written*/) {
3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  lock_.AssertAcquired();
3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!is_closed_);
3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // By default, not supported. Only needed for data pipe dispatchers.
3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return MOJO_RESULT_INVALID_ARGUMENT;
3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)MojoResult Dispatcher::ReadDataImplNoLock(UserPointer<void> /*elements*/,
3195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                          UserPointer<uint32_t> /*num_bytes*/,
3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                          MojoReadDataFlags /*flags*/) {
3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  lock_.AssertAcquired();
3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!is_closed_);
3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // By default, not supported. Only needed for data pipe dispatchers.
3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return MOJO_RESULT_INVALID_ARGUMENT;
3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)MojoResult Dispatcher::BeginReadDataImplNoLock(
3285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    UserPointer<const void*> /*buffer*/,
3295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    UserPointer<uint32_t> /*buffer_num_bytes*/,
3305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    MojoReadDataFlags /*flags*/) {
3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  lock_.AssertAcquired();
3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!is_closed_);
3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // By default, not supported. Only needed for data pipe dispatchers.
3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return MOJO_RESULT_INVALID_ARGUMENT;
3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)MojoResult Dispatcher::EndReadDataImplNoLock(uint32_t /*num_bytes_read*/) {
3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  lock_.AssertAcquired();
3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!is_closed_);
3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // By default, not supported. Only needed for data pipe dispatchers.
3414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return MOJO_RESULT_INVALID_ARGUMENT;
3424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
3434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
344a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)MojoResult Dispatcher::DuplicateBufferHandleImplNoLock(
3455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    UserPointer<const MojoDuplicateBufferHandleOptions> /*options*/,
3465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    scoped_refptr<Dispatcher>* /*new_dispatcher*/) {
347a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  lock_.AssertAcquired();
348a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(!is_closed_);
349a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // By default, not supported. Only needed for buffer dispatchers.
350a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return MOJO_RESULT_INVALID_ARGUMENT;
351a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
352a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
353effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochMojoResult Dispatcher::MapBufferImplNoLock(
354effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    uint64_t /*offset*/,
355effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    uint64_t /*num_bytes*/,
356effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    MojoMapBufferFlags /*flags*/,
3576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    scoped_ptr<embedder::PlatformSharedBufferMapping>* /*mapping*/) {
358a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  lock_.AssertAcquired();
359a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(!is_closed_);
360a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // By default, not supported. Only needed for buffer dispatchers.
361a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return MOJO_RESULT_INVALID_ARGUMENT;
362a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
363a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
3645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)HandleSignalsState Dispatcher::GetHandleSignalsStateImplNoLock() const {
3655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  lock_.AssertAcquired();
3665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(!is_closed_);
3675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // By default, waiting isn't supported. Only dispatchers that can be waited on
3685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // will do something nontrivial.
3695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return HandleSignalsState();
3705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)MojoResult Dispatcher::AddWaiterImplNoLock(Waiter* /*waiter*/,
373f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                           MojoHandleSignals /*signals*/,
3745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                           uint32_t /*context*/,
3755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                           HandleSignalsState* signals_state) {
3764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  lock_.AssertAcquired();
3774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(!is_closed_);
3784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // By default, waiting isn't supported. Only dispatchers that can be waited on
3794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // will do something nontrivial.
3805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (signals_state)
3815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    *signals_state = HandleSignalsState();
3824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return MOJO_RESULT_FAILED_PRECONDITION;
3834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
3844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void Dispatcher::RemoveWaiterImplNoLock(Waiter* /*waiter*/,
3865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                        HandleSignalsState* signals_state) {
3874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  lock_.AssertAcquired();
3884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(!is_closed_);
3894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // By default, waiting isn't supported. Only dispatchers that can be waited on
3904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // will do something nontrivial.
3915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (signals_state)
3925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    *signals_state = HandleSignalsState();
3934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
3944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
395c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid Dispatcher::StartSerializeImplNoLock(Channel* /*channel*/,
396c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                          size_t* max_size,
397c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                          size_t* max_platform_handles) {
398c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DCHECK(HasOneRef());  // Only one ref => no need to take the lock.
399a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(!is_closed_);
400c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  *max_size = 0;
401c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  *max_platform_handles = 0;
402a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
403a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
404c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochbool Dispatcher::EndSerializeAndCloseImplNoLock(
405c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    Channel* /*channel*/,
406c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    void* /*destination*/,
407c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    size_t* /*actual_size*/,
408cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    embedder::PlatformHandleVector* /*platform_handles*/) {
409c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DCHECK(HasOneRef());  // Only one ref => no need to take the lock.
410a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(is_closed_);
411a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // By default, serializing isn't supported, so just close.
412a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  CloseImplNoLock();
413c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return false;
414a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
415a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool Dispatcher::IsBusyNoLock() const {
4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  lock_.AssertAcquired();
4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!is_closed_);
4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Most dispatchers support only "atomic" operations, so they are never busy
4205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // (in this sense).
4215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return false;
4225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void Dispatcher::CloseNoLock() {
4255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  lock_.AssertAcquired();
4265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!is_closed_);
4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  is_closed_ = true;
4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CancelAllWaitersNoLock();
4305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CloseImplNoLock();
4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)scoped_refptr<Dispatcher>
4345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)Dispatcher::CreateEquivalentDispatcherAndCloseNoLock() {
4355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  lock_.AssertAcquired();
4365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!is_closed_);
4375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  is_closed_ = true;
4395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CancelAllWaitersNoLock();
4405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return CreateEquivalentDispatcherAndCloseImplNoLock();
4415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
443c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid Dispatcher::StartSerialize(Channel* channel,
444c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                size_t* max_size,
445c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                size_t* max_platform_handles) {
446a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(channel);
447c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DCHECK(max_size);
448c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DCHECK(max_platform_handles);
449c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DCHECK(HasOneRef());  // Only one ref => no need to take the lock.
450a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(!is_closed_);
451c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  StartSerializeImplNoLock(channel, max_size, max_platform_handles);
452a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
453a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
454c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochbool Dispatcher::EndSerializeAndClose(
455c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    Channel* channel,
456c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    void* destination,
457c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    size_t* actual_size,
458cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    embedder::PlatformHandleVector* platform_handles) {
459a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(channel);
460a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(actual_size);
461c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DCHECK(HasOneRef());  // Only one ref => no need to take the lock.
462a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(!is_closed_);
463a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
464a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Like other |...Close()| methods, we mark ourselves as closed before calling
4655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // the impl. But there's no need to cancel waiters: we shouldn't have any (and
4665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // shouldn't be in |Core|'s handle table.
467a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  is_closed_ = true;
468a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
469c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#if !defined(NDEBUG)
470c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // See the comment above |EndSerializeAndCloseImplNoLock()|. In brief: Locking
471c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // isn't actually needed, but we need to satisfy assertions (which we don't
472c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // want to remove or weaken).
473c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  base::AutoLock locker(lock_);
474c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#endif
475a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
4765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return EndSerializeAndCloseImplNoLock(
4775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      channel, destination, actual_size, platform_handles);
478a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
479a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
4805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// DispatcherTransport ---------------------------------------------------------
4815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DispatcherTransport::End() {
4835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(dispatcher_);
4845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  dispatcher_->lock_.Release();
4851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  dispatcher_ = nullptr;
4865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}  // namespace system
4894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}  // namespace mojo
490