| OLD | NEW | 
|---|
| 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 <stddef.h> |  | 
| 8 #include <stdint.h> |  | 
| 9 |  | 
| 10 #include "base/logging.h" | 7 #include "base/logging.h" | 
| 11 #include "mojo/edk/system/configuration.h" | 8 #include "mojo/edk/system/configuration.h" | 
| 12 #include "mojo/edk/system/data_pipe_consumer_dispatcher.h" | 9 #include "mojo/edk/system/data_pipe_consumer_dispatcher.h" | 
| 13 #include "mojo/edk/system/data_pipe_producer_dispatcher.h" | 10 #include "mojo/edk/system/data_pipe_producer_dispatcher.h" | 
| 14 #include "mojo/edk/system/message_pipe_dispatcher.h" | 11 #include "mojo/edk/system/message_pipe_dispatcher.h" | 
| 15 #include "mojo/edk/system/platform_handle_dispatcher.h" | 12 #include "mojo/edk/system/platform_handle_dispatcher.h" | 
| 16 #include "mojo/edk/system/shared_buffer_dispatcher.h" | 13 #include "mojo/edk/system/shared_buffer_dispatcher.h" | 
| 17 | 14 | 
| 18 namespace mojo { | 15 namespace mojo { | 
| 19 namespace edk { | 16 namespace edk { | 
| 20 | 17 | 
| 21 namespace test { | 18 Dispatcher::DispatcherInTransit::DispatcherInTransit() {} | 
| 22 | 19 | 
| 23 // TODO(vtl): Maybe this should be defined in a test-only file instead. | 20 Dispatcher::DispatcherInTransit::~DispatcherInTransit() {} | 
| 24 DispatcherTransport DispatcherTryStartTransport(Dispatcher* dispatcher) { |  | 
| 25   return Dispatcher::HandleTableAccess::TryStartTransport(dispatcher); |  | 
| 26 } |  | 
| 27 | 21 | 
| 28 }  // namespace test | 22 MojoResult Dispatcher::WriteMessage(const void* bytes, | 
| 29 | 23                                     uint32_t num_bytes, | 
| 30 // Dispatcher ------------------------------------------------------------------ | 24                                     const DispatcherInTransit* dispatchers, | 
| 31 | 25                                     uint32_t num_dispatchers, | 
| 32 // static | 26                                     MojoWriteMessageFlags flags) { | 
| 33 DispatcherTransport Dispatcher::HandleTableAccess::TryStartTransport( | 27   return MOJO_RESULT_INVALID_ARGUMENT; | 
| 34     Dispatcher* dispatcher) { |  | 
| 35   DCHECK(dispatcher); |  | 
| 36 |  | 
| 37   // Our dispatcher implementations hop to IO thread on initialization, so it's |  | 
| 38   // valid that while their RawChannel os being initialized on IO thread, the |  | 
| 39   // dispatcher is being sent. We handle this by just acquiring the lock. |  | 
| 40 |  | 
| 41   // See comment in header for why we need this. |  | 
| 42   dispatcher->TransportStarted(); |  | 
| 43 |  | 
| 44   dispatcher->lock_.Acquire(); |  | 
| 45 |  | 
| 46   // We shouldn't race with things that close dispatchers, since closing can |  | 
| 47   // only take place either under |handle_table_lock_| or when the handle is |  | 
| 48   // marked as busy. |  | 
| 49   DCHECK(!dispatcher->is_closed_); |  | 
| 50 |  | 
| 51   return DispatcherTransport(dispatcher); |  | 
| 52 } |  | 
| 53 |  | 
| 54 // static |  | 
| 55 void Dispatcher::TransportDataAccess::StartSerialize( |  | 
| 56     Dispatcher* dispatcher, |  | 
| 57     size_t* max_size, |  | 
| 58     size_t* max_platform_handles) { |  | 
| 59   DCHECK(dispatcher); |  | 
| 60   dispatcher->StartSerialize(max_size, max_platform_handles); |  | 
| 61 } |  | 
| 62 |  | 
| 63 // static |  | 
| 64 bool Dispatcher::TransportDataAccess::EndSerializeAndClose( |  | 
| 65     Dispatcher* dispatcher, |  | 
| 66     void* destination, |  | 
| 67     size_t* actual_size, |  | 
| 68     PlatformHandleVector* platform_handles) { |  | 
| 69   DCHECK(dispatcher); |  | 
| 70   return dispatcher->EndSerializeAndClose(destination, actual_size, |  | 
| 71                                           platform_handles); |  | 
| 72 } |  | 
| 73 |  | 
| 74 // static |  | 
| 75 scoped_refptr<Dispatcher> Dispatcher::TransportDataAccess::Deserialize( |  | 
| 76     int32_t type, |  | 
| 77     const void* source, |  | 
| 78     size_t size, |  | 
| 79     PlatformHandleVector* platform_handles) { |  | 
| 80   switch (static_cast<Dispatcher::Type>(type)) { |  | 
| 81     case Type::UNKNOWN: |  | 
| 82     case Type::WAIT_SET: |  | 
| 83       DVLOG(2) << "Deserializing invalid handle"; |  | 
| 84       return nullptr; |  | 
| 85     case Type::MESSAGE_PIPE: |  | 
| 86       return scoped_refptr<Dispatcher>(MessagePipeDispatcher::Deserialize( |  | 
| 87           source, size, platform_handles)); |  | 
| 88     case Type::DATA_PIPE_PRODUCER: |  | 
| 89       return scoped_refptr<Dispatcher>( |  | 
| 90           DataPipeProducerDispatcher::Deserialize( |  | 
| 91               source, size, platform_handles)); |  | 
| 92     case Type::DATA_PIPE_CONSUMER: |  | 
| 93       return scoped_refptr<Dispatcher>( |  | 
| 94           DataPipeConsumerDispatcher::Deserialize( |  | 
| 95               source, size, platform_handles)); |  | 
| 96     case Type::SHARED_BUFFER: |  | 
| 97       return scoped_refptr<Dispatcher>(SharedBufferDispatcher::Deserialize( |  | 
| 98           source, size, platform_handles)); |  | 
| 99     case Type::PLATFORM_HANDLE: |  | 
| 100       return scoped_refptr<Dispatcher>(PlatformHandleDispatcher::Deserialize( |  | 
| 101           source, size, platform_handles)); |  | 
| 102   } |  | 
| 103   LOG(WARNING) << "Unknown dispatcher type " << type; |  | 
| 104   return nullptr; |  | 
| 105 } |  | 
| 106 |  | 
| 107 MojoResult Dispatcher::Close() { |  | 
| 108   base::AutoLock locker(lock_); |  | 
| 109   if (is_closed_) |  | 
| 110     return MOJO_RESULT_INVALID_ARGUMENT; |  | 
| 111 |  | 
| 112   CloseNoLock(); |  | 
| 113   return MOJO_RESULT_OK; |  | 
| 114 } |  | 
| 115 |  | 
| 116 MojoResult Dispatcher::WriteMessage( |  | 
| 117     const void* bytes, |  | 
| 118     uint32_t num_bytes, |  | 
| 119     std::vector<DispatcherTransport>* transports, |  | 
| 120     MojoWriteMessageFlags flags) { |  | 
| 121   DCHECK(!transports || |  | 
| 122          (transports->size() > 0 && |  | 
| 123           transports->size() < GetConfiguration().max_message_num_handles)); |  | 
| 124 |  | 
| 125   base::AutoLock locker(lock_); |  | 
| 126   if (is_closed_) |  | 
| 127     return MOJO_RESULT_INVALID_ARGUMENT; |  | 
| 128 |  | 
| 129   return WriteMessageImplNoLock(bytes, num_bytes, transports, flags); |  | 
| 130 } | 28 } | 
| 131 | 29 | 
| 132 MojoResult Dispatcher::ReadMessage(void* bytes, | 30 MojoResult Dispatcher::ReadMessage(void* bytes, | 
| 133                                    uint32_t* num_bytes, | 31                                    uint32_t* num_bytes, | 
| 134                                    DispatcherVector* dispatchers, | 32                                    MojoHandle* handles, | 
| 135                                    uint32_t* num_dispatchers, | 33                                    uint32_t* num_handles, | 
| 136                                    MojoReadMessageFlags flags) { | 34                                    MojoReadMessageFlags flags) { | 
| 137   DCHECK(!num_dispatchers || *num_dispatchers == 0 || | 35   return MOJO_RESULT_INVALID_ARGUMENT; | 
| 138          (dispatchers && dispatchers->empty())); |  | 
| 139 |  | 
| 140   base::AutoLock locker(lock_); |  | 
| 141   if (is_closed_) |  | 
| 142     return MOJO_RESULT_INVALID_ARGUMENT; |  | 
| 143 |  | 
| 144   return ReadMessageImplNoLock(bytes, num_bytes, dispatchers, num_dispatchers, |  | 
| 145                                flags); |  | 
| 146 } |  | 
| 147 |  | 
| 148 MojoResult Dispatcher::WriteData(const void* elements, |  | 
| 149                                  uint32_t* num_bytes, |  | 
| 150                                  MojoWriteDataFlags flags) { |  | 
| 151   base::AutoLock locker(lock_); |  | 
| 152   if (is_closed_) |  | 
| 153     return MOJO_RESULT_INVALID_ARGUMENT; |  | 
| 154 |  | 
| 155   return WriteDataImplNoLock(elements, num_bytes, flags); |  | 
| 156 } |  | 
| 157 |  | 
| 158 MojoResult Dispatcher::BeginWriteData(void** buffer, |  | 
| 159                                       uint32_t* buffer_num_bytes, |  | 
| 160                                       MojoWriteDataFlags flags) { |  | 
| 161   base::AutoLock locker(lock_); |  | 
| 162   if (is_closed_) |  | 
| 163     return MOJO_RESULT_INVALID_ARGUMENT; |  | 
| 164 |  | 
| 165   return BeginWriteDataImplNoLock(buffer, buffer_num_bytes, flags); |  | 
| 166 } |  | 
| 167 |  | 
| 168 MojoResult Dispatcher::EndWriteData(uint32_t num_bytes_written) { |  | 
| 169   base::AutoLock locker(lock_); |  | 
| 170   if (is_closed_) |  | 
| 171     return MOJO_RESULT_INVALID_ARGUMENT; |  | 
| 172 |  | 
| 173   return EndWriteDataImplNoLock(num_bytes_written); |  | 
| 174 } |  | 
| 175 |  | 
| 176 MojoResult Dispatcher::ReadData(void* elements, |  | 
| 177                                 uint32_t* num_bytes, |  | 
| 178                                 MojoReadDataFlags flags) { |  | 
| 179   base::AutoLock locker(lock_); |  | 
| 180   if (is_closed_) |  | 
| 181     return MOJO_RESULT_INVALID_ARGUMENT; |  | 
| 182 |  | 
| 183   return ReadDataImplNoLock(elements, num_bytes, flags); |  | 
| 184 } |  | 
| 185 |  | 
| 186 MojoResult Dispatcher::BeginReadData(const void** buffer, |  | 
| 187                                      uint32_t* buffer_num_bytes, |  | 
| 188                                      MojoReadDataFlags flags) { |  | 
| 189   base::AutoLock locker(lock_); |  | 
| 190   if (is_closed_) |  | 
| 191     return MOJO_RESULT_INVALID_ARGUMENT; |  | 
| 192 |  | 
| 193   return BeginReadDataImplNoLock(buffer, buffer_num_bytes, flags); |  | 
| 194 } |  | 
| 195 |  | 
| 196 MojoResult Dispatcher::EndReadData(uint32_t num_bytes_read) { |  | 
| 197   base::AutoLock locker(lock_); |  | 
| 198   if (is_closed_) |  | 
| 199     return MOJO_RESULT_INVALID_ARGUMENT; |  | 
| 200 |  | 
| 201   return EndReadDataImplNoLock(num_bytes_read); |  | 
| 202 } | 36 } | 
| 203 | 37 | 
| 204 MojoResult Dispatcher::DuplicateBufferHandle( | 38 MojoResult Dispatcher::DuplicateBufferHandle( | 
| 205     const MojoDuplicateBufferHandleOptions* options, | 39     const MojoDuplicateBufferHandleOptions* options, | 
| 206     scoped_refptr<Dispatcher>* new_dispatcher) { | 40     scoped_refptr<Dispatcher>* new_dispatcher) { | 
| 207   base::AutoLock locker(lock_); | 41   return MOJO_RESULT_INVALID_ARGUMENT; | 
| 208   if (is_closed_) |  | 
| 209     return MOJO_RESULT_INVALID_ARGUMENT; |  | 
| 210 |  | 
| 211   return DuplicateBufferHandleImplNoLock(options, new_dispatcher); |  | 
| 212 } | 42 } | 
| 213 | 43 | 
| 214 MojoResult Dispatcher::MapBuffer( | 44 MojoResult Dispatcher::MapBuffer( | 
| 215     uint64_t offset, | 45     uint64_t offset, | 
| 216     uint64_t num_bytes, | 46     uint64_t num_bytes, | 
| 217     MojoMapBufferFlags flags, | 47     MojoMapBufferFlags flags, | 
| 218     scoped_ptr<PlatformSharedBufferMapping>* mapping) { | 48     scoped_ptr<PlatformSharedBufferMapping>* mapping) { | 
| 219   base::AutoLock locker(lock_); | 49   return MOJO_RESULT_INVALID_ARGUMENT; | 
| 220   if (is_closed_) | 50 } | 
| 221     return MOJO_RESULT_INVALID_ARGUMENT; |  | 
| 222 | 51 | 
| 223   return MapBufferImplNoLock(offset, num_bytes, flags, mapping); | 52 MojoResult Dispatcher::ReadData(void* elements, | 
|  | 53                                 uint32_t* num_bytes, | 
|  | 54                                 MojoReadDataFlags flags) { | 
|  | 55   return MOJO_RESULT_INVALID_ARGUMENT; | 
|  | 56 } | 
|  | 57 | 
|  | 58 MojoResult Dispatcher::BeginReadData(const void** buffer, | 
|  | 59                                      uint32_t* buffer_num_bytes, | 
|  | 60                                      MojoReadDataFlags flags) { | 
|  | 61   return MOJO_RESULT_INVALID_ARGUMENT; | 
|  | 62 } | 
|  | 63 | 
|  | 64 MojoResult Dispatcher::EndReadData(uint32_t num_bytes_read) { | 
|  | 65   return MOJO_RESULT_INVALID_ARGUMENT; | 
|  | 66 } | 
|  | 67 | 
|  | 68 MojoResult Dispatcher::WriteData(const void* elements, | 
|  | 69                                  uint32_t* num_bytes, | 
|  | 70                                  MojoWriteDataFlags flags) { | 
|  | 71   return MOJO_RESULT_INVALID_ARGUMENT; | 
|  | 72 } | 
|  | 73 | 
|  | 74 MojoResult Dispatcher::BeginWriteData(void** buffer, | 
|  | 75                                       uint32_t* buffer_num_bytes, | 
|  | 76                                       MojoWriteDataFlags flags) { | 
|  | 77   return MOJO_RESULT_INVALID_ARGUMENT; | 
|  | 78 } | 
|  | 79 | 
|  | 80 MojoResult Dispatcher::EndWriteData(uint32_t num_bytes_written) { | 
|  | 81   return MOJO_RESULT_INVALID_ARGUMENT; | 
|  | 82 } | 
|  | 83 | 
|  | 84 MojoResult Dispatcher::AddWaitingDispatcher( | 
|  | 85     const scoped_refptr<Dispatcher>& dispatcher, | 
|  | 86     MojoHandleSignals signals, | 
|  | 87     uintptr_t context) { | 
|  | 88   return MOJO_RESULT_INVALID_ARGUMENT; | 
|  | 89 } | 
|  | 90 | 
|  | 91 MojoResult Dispatcher::RemoveWaitingDispatcher( | 
|  | 92     const scoped_refptr<Dispatcher>& dispatcher) { | 
|  | 93   return MOJO_RESULT_INVALID_ARGUMENT; | 
|  | 94 } | 
|  | 95 | 
|  | 96 MojoResult Dispatcher::GetReadyDispatchers(uint32_t* count, | 
|  | 97                                            DispatcherVector* dispatchers, | 
|  | 98                                            MojoResult* results, | 
|  | 99                                            uintptr_t* contexts) { | 
|  | 100   return MOJO_RESULT_INVALID_ARGUMENT; | 
| 224 } | 101 } | 
| 225 | 102 | 
| 226 HandleSignalsState Dispatcher::GetHandleSignalsState() const { | 103 HandleSignalsState Dispatcher::GetHandleSignalsState() const { | 
| 227   base::AutoLock locker(lock_); | 104   return HandleSignalsState(); | 
| 228   if (is_closed_) |  | 
| 229     return HandleSignalsState(); |  | 
| 230 |  | 
| 231   return GetHandleSignalsStateImplNoLock(); |  | 
| 232 } | 105 } | 
| 233 | 106 | 
| 234 MojoResult Dispatcher::AddAwakable(Awakable* awakable, | 107 MojoResult Dispatcher::AddAwakable(Awakable* awakable, | 
| 235                                    MojoHandleSignals signals, | 108                                    MojoHandleSignals signals, | 
| 236                                    uintptr_t context, | 109                                    uintptr_t context, | 
| 237                                    HandleSignalsState* signals_state) { | 110                                    HandleSignalsState* signals_state) { | 
| 238   base::AutoLock locker(lock_); | 111   return MOJO_RESULT_INVALID_ARGUMENT; | 
| 239   if (is_closed_) { |  | 
| 240     if (signals_state) |  | 
| 241       *signals_state = HandleSignalsState(); |  | 
| 242     return MOJO_RESULT_INVALID_ARGUMENT; |  | 
| 243   } |  | 
| 244 |  | 
| 245   return AddAwakableImplNoLock(awakable, signals, context, signals_state); |  | 
| 246 } | 112 } | 
| 247 | 113 | 
| 248 void Dispatcher::RemoveAwakable(Awakable* awakable, | 114 void Dispatcher::RemoveAwakable(Awakable* awakable, | 
| 249                                 HandleSignalsState* handle_signals_state) { | 115                                 HandleSignalsState* handle_signals_state) { | 
| 250   base::AutoLock locker(lock_); | 116   NOTREACHED(); | 
| 251   if (is_closed_) { |  | 
| 252     if (handle_signals_state) |  | 
| 253       *handle_signals_state = HandleSignalsState(); |  | 
| 254     return; |  | 
| 255   } |  | 
| 256 |  | 
| 257   RemoveAwakableImplNoLock(awakable, handle_signals_state); |  | 
| 258 } | 117 } | 
| 259 | 118 | 
| 260 MojoResult Dispatcher::AddWaitingDispatcher( | 119 void Dispatcher::StartSerialize(uint32_t* num_bytes, | 
| 261     const scoped_refptr<Dispatcher>& dispatcher, | 120                                 uint32_t* num_ports, | 
| 262     MojoHandleSignals signals, | 121                                 uint32_t* num_platform_handles) { | 
| 263     uintptr_t context) { | 122   *num_bytes = 0; | 
| 264   base::AutoLock locker(lock_); | 123   *num_ports = 0; | 
| 265   if (is_closed_) | 124   *num_platform_handles = 0; | 
| 266     return MOJO_RESULT_INVALID_ARGUMENT; |  | 
| 267 |  | 
| 268   return AddWaitingDispatcherImplNoLock(dispatcher, signals, context); |  | 
| 269 } | 125 } | 
| 270 | 126 | 
| 271 MojoResult Dispatcher::RemoveWaitingDispatcher( | 127 bool Dispatcher::EndSerialize(void* destination, | 
| 272     const scoped_refptr<Dispatcher>& dispatcher) { | 128                               ports::PortName* ports, | 
| 273   base::AutoLock locker(lock_); | 129                               PlatformHandle* handles) { | 
| 274   if (is_closed_) | 130   LOG(ERROR) << "Attempting to serialize a non-transferrable dispatcher."; | 
| 275     return MOJO_RESULT_INVALID_ARGUMENT; | 131   return true; | 
| 276 |  | 
| 277   return RemoveWaitingDispatcherImplNoLock(dispatcher); |  | 
| 278 } | 132 } | 
| 279 | 133 | 
| 280 MojoResult Dispatcher::GetReadyDispatchers(uint32_t* count, | 134 bool Dispatcher::BeginTransit() { return true; } | 
| 281                                            DispatcherVector* dispatchers, |  | 
| 282                                            MojoResult* results, |  | 
| 283                                            uintptr_t* contexts) { |  | 
| 284   base::AutoLock locker(lock_); |  | 
| 285   if (is_closed_) |  | 
| 286     return MOJO_RESULT_INVALID_ARGUMENT; |  | 
| 287 | 135 | 
| 288   return GetReadyDispatchersImplNoLock(count, dispatchers, results, contexts); | 136 void Dispatcher::CompleteTransitAndClose() {} | 
|  | 137 | 
|  | 138 void Dispatcher::CancelTransit() {} | 
|  | 139 | 
|  | 140 // static | 
|  | 141 scoped_refptr<Dispatcher> Dispatcher::Deserialize( | 
|  | 142     Type type, | 
|  | 143     const void* bytes, | 
|  | 144     size_t num_bytes, | 
|  | 145     const ports::PortName* ports, | 
|  | 146     size_t num_ports, | 
|  | 147     PlatformHandle* platform_handles, | 
|  | 148     size_t num_platform_handles) { | 
|  | 149   switch (type) { | 
|  | 150     case Type::MESSAGE_PIPE: | 
|  | 151       return MessagePipeDispatcher::Deserialize( | 
|  | 152           bytes, num_bytes, ports, num_ports, platform_handles, | 
|  | 153           num_platform_handles); | 
|  | 154     case Type::SHARED_BUFFER: | 
|  | 155       return SharedBufferDispatcher::Deserialize( | 
|  | 156           bytes, num_bytes, ports, num_ports, platform_handles, | 
|  | 157           num_platform_handles); | 
|  | 158     case Type::DATA_PIPE_CONSUMER: | 
|  | 159       return DataPipeConsumerDispatcher::Deserialize( | 
|  | 160           bytes, num_bytes, ports, num_ports, platform_handles, | 
|  | 161           num_platform_handles); | 
|  | 162     case Type::DATA_PIPE_PRODUCER: | 
|  | 163       return DataPipeProducerDispatcher::Deserialize( | 
|  | 164           bytes, num_bytes, ports, num_ports, platform_handles, | 
|  | 165           num_platform_handles); | 
|  | 166     case Type::PLATFORM_HANDLE: | 
|  | 167       return PlatformHandleDispatcher::Deserialize( | 
|  | 168           bytes, num_bytes, ports, num_ports, platform_handles, | 
|  | 169           num_platform_handles); | 
|  | 170     default: | 
|  | 171       LOG(ERROR) << "Deserializing invalid dispatcher type."; | 
|  | 172       return nullptr; | 
|  | 173   } | 
| 289 } | 174 } | 
| 290 | 175 | 
| 291 Dispatcher::Dispatcher() : is_closed_(false) { | 176 Dispatcher::Dispatcher() {} | 
| 292 } |  | 
| 293 | 177 | 
| 294 Dispatcher::~Dispatcher() { | 178 Dispatcher::~Dispatcher() {} | 
| 295   // Make sure that |Close()| was called. |  | 
| 296   DCHECK(is_closed_); |  | 
| 297 } |  | 
| 298 |  | 
| 299 void Dispatcher::CancelAllAwakablesNoLock() { |  | 
| 300   lock_.AssertAcquired(); |  | 
| 301   DCHECK(is_closed_); |  | 
| 302   // By default, waiting isn't supported. Only dispatchers that can be waited on |  | 
| 303   // will do something nontrivial. |  | 
| 304 } |  | 
| 305 |  | 
| 306 void Dispatcher::CloseImplNoLock() { |  | 
| 307   lock_.AssertAcquired(); |  | 
| 308   DCHECK(is_closed_); |  | 
| 309   // This may not need to do anything. Dispatchers should override this to do |  | 
| 310   // any actual close-time cleanup necessary. |  | 
| 311 } |  | 
| 312 |  | 
| 313 MojoResult Dispatcher::WriteMessageImplNoLock( |  | 
| 314     const void* /*bytes*/, |  | 
| 315     uint32_t /*num_bytes*/, |  | 
| 316     std::vector<DispatcherTransport>* /*transports*/, |  | 
| 317     MojoWriteMessageFlags /*flags*/) { |  | 
| 318   lock_.AssertAcquired(); |  | 
| 319   DCHECK(!is_closed_); |  | 
| 320   // By default, not supported. Only needed for message pipe dispatchers. |  | 
| 321   return MOJO_RESULT_INVALID_ARGUMENT; |  | 
| 322 } |  | 
| 323 |  | 
| 324 MojoResult Dispatcher::ReadMessageImplNoLock( |  | 
| 325     void* /*bytes*/, |  | 
| 326     uint32_t* /*num_bytes*/, |  | 
| 327     DispatcherVector* /*dispatchers*/, |  | 
| 328     uint32_t* /*num_dispatchers*/, |  | 
| 329     MojoReadMessageFlags /*flags*/) { |  | 
| 330   lock_.AssertAcquired(); |  | 
| 331   DCHECK(!is_closed_); |  | 
| 332   // By default, not supported. Only needed for message pipe dispatchers. |  | 
| 333   return MOJO_RESULT_INVALID_ARGUMENT; |  | 
| 334 } |  | 
| 335 |  | 
| 336 MojoResult Dispatcher::WriteDataImplNoLock(const void* /*elements*/, |  | 
| 337                                            uint32_t* /*num_bytes*/, |  | 
| 338                                            MojoWriteDataFlags /*flags*/) { |  | 
| 339   lock_.AssertAcquired(); |  | 
| 340   DCHECK(!is_closed_); |  | 
| 341   // By default, not supported. Only needed for data pipe dispatchers. |  | 
| 342   return MOJO_RESULT_INVALID_ARGUMENT; |  | 
| 343 } |  | 
| 344 |  | 
| 345 MojoResult Dispatcher::BeginWriteDataImplNoLock( |  | 
| 346     void** /*buffer*/, |  | 
| 347     uint32_t* /*buffer_num_bytes*/, |  | 
| 348     MojoWriteDataFlags /*flags*/) { |  | 
| 349   lock_.AssertAcquired(); |  | 
| 350   DCHECK(!is_closed_); |  | 
| 351   // By default, not supported. Only needed for data pipe dispatchers. |  | 
| 352   return MOJO_RESULT_INVALID_ARGUMENT; |  | 
| 353 } |  | 
| 354 |  | 
| 355 MojoResult Dispatcher::EndWriteDataImplNoLock(uint32_t /*num_bytes_written*/) { |  | 
| 356   lock_.AssertAcquired(); |  | 
| 357   DCHECK(!is_closed_); |  | 
| 358   // By default, not supported. Only needed for data pipe dispatchers. |  | 
| 359   return MOJO_RESULT_INVALID_ARGUMENT; |  | 
| 360 } |  | 
| 361 |  | 
| 362 MojoResult Dispatcher::ReadDataImplNoLock(void* /*elements*/, |  | 
| 363                                           uint32_t* /*num_bytes*/, |  | 
| 364                                           MojoReadDataFlags /*flags*/) { |  | 
| 365   lock_.AssertAcquired(); |  | 
| 366   DCHECK(!is_closed_); |  | 
| 367   // By default, not supported. Only needed for data pipe dispatchers. |  | 
| 368   return MOJO_RESULT_INVALID_ARGUMENT; |  | 
| 369 } |  | 
| 370 |  | 
| 371 MojoResult Dispatcher::BeginReadDataImplNoLock( |  | 
| 372     const void** /*buffer*/, |  | 
| 373     uint32_t* /*buffer_num_bytes*/, |  | 
| 374     MojoReadDataFlags /*flags*/) { |  | 
| 375   lock_.AssertAcquired(); |  | 
| 376   DCHECK(!is_closed_); |  | 
| 377   // By default, not supported. Only needed for data pipe dispatchers. |  | 
| 378   return MOJO_RESULT_INVALID_ARGUMENT; |  | 
| 379 } |  | 
| 380 |  | 
| 381 MojoResult Dispatcher::EndReadDataImplNoLock(uint32_t /*num_bytes_read*/) { |  | 
| 382   lock_.AssertAcquired(); |  | 
| 383   DCHECK(!is_closed_); |  | 
| 384   // By default, not supported. Only needed for data pipe dispatchers. |  | 
| 385   return MOJO_RESULT_INVALID_ARGUMENT; |  | 
| 386 } |  | 
| 387 |  | 
| 388 MojoResult Dispatcher::DuplicateBufferHandleImplNoLock( |  | 
| 389     const MojoDuplicateBufferHandleOptions* /*options*/, |  | 
| 390     scoped_refptr<Dispatcher>* /*new_dispatcher*/) { |  | 
| 391   lock_.AssertAcquired(); |  | 
| 392   DCHECK(!is_closed_); |  | 
| 393   // By default, not supported. Only needed for buffer dispatchers. |  | 
| 394   return MOJO_RESULT_INVALID_ARGUMENT; |  | 
| 395 } |  | 
| 396 |  | 
| 397 MojoResult Dispatcher::MapBufferImplNoLock( |  | 
| 398     uint64_t /*offset*/, |  | 
| 399     uint64_t /*num_bytes*/, |  | 
| 400     MojoMapBufferFlags /*flags*/, |  | 
| 401     scoped_ptr<PlatformSharedBufferMapping>* /*mapping*/) { |  | 
| 402   lock_.AssertAcquired(); |  | 
| 403   DCHECK(!is_closed_); |  | 
| 404   // By default, not supported. Only needed for buffer dispatchers. |  | 
| 405   return MOJO_RESULT_INVALID_ARGUMENT; |  | 
| 406 } |  | 
| 407 |  | 
| 408 HandleSignalsState Dispatcher::GetHandleSignalsStateImplNoLock() const { |  | 
| 409   lock_.AssertAcquired(); |  | 
| 410   DCHECK(!is_closed_); |  | 
| 411   // By default, waiting isn't supported. Only dispatchers that can be waited on |  | 
| 412   // will do something nontrivial. |  | 
| 413   return HandleSignalsState(); |  | 
| 414 } |  | 
| 415 |  | 
| 416 MojoResult Dispatcher::AddAwakableImplNoLock( |  | 
| 417     Awakable* /*awakable*/, |  | 
| 418     MojoHandleSignals /*signals*/, |  | 
| 419     uintptr_t /*context*/, |  | 
| 420     HandleSignalsState* signals_state) { |  | 
| 421   lock_.AssertAcquired(); |  | 
| 422   DCHECK(!is_closed_); |  | 
| 423   // By default, waiting isn't supported. Only dispatchers that can be waited on |  | 
| 424   // will do something nontrivial. |  | 
| 425   if (signals_state) |  | 
| 426     *signals_state = HandleSignalsState(); |  | 
| 427   return MOJO_RESULT_FAILED_PRECONDITION; |  | 
| 428 } |  | 
| 429 |  | 
| 430 MojoResult Dispatcher::AddWaitingDispatcherImplNoLock( |  | 
| 431     const scoped_refptr<Dispatcher>& /*dispatcher*/, |  | 
| 432     MojoHandleSignals /*signals*/, |  | 
| 433     uintptr_t /*context*/) { |  | 
| 434   lock_.AssertAcquired(); |  | 
| 435   DCHECK(!is_closed_); |  | 
| 436   // By default, not supported. Only needed for wait set dispatchers. |  | 
| 437   return MOJO_RESULT_INVALID_ARGUMENT; |  | 
| 438 } |  | 
| 439 |  | 
| 440 MojoResult Dispatcher::RemoveWaitingDispatcherImplNoLock( |  | 
| 441     const scoped_refptr<Dispatcher>& /*dispatcher*/) { |  | 
| 442   lock_.AssertAcquired(); |  | 
| 443   DCHECK(!is_closed_); |  | 
| 444   // By default, not supported. Only needed for wait set dispatchers. |  | 
| 445   return MOJO_RESULT_INVALID_ARGUMENT; |  | 
| 446 } |  | 
| 447 |  | 
| 448 MojoResult Dispatcher::GetReadyDispatchersImplNoLock( |  | 
| 449     uint32_t* /*count*/, |  | 
| 450     DispatcherVector* /*dispatchers*/, |  | 
| 451     MojoResult* /*results*/, |  | 
| 452     uintptr_t* /*contexts*/) { |  | 
| 453   lock_.AssertAcquired(); |  | 
| 454   DCHECK(!is_closed_); |  | 
| 455   // By default, not supported. Only needed for wait set dispatchers. |  | 
| 456   return MOJO_RESULT_INVALID_ARGUMENT; |  | 
| 457 } |  | 
| 458 |  | 
| 459 void Dispatcher::RemoveAwakableImplNoLock(Awakable* /*awakable*/, |  | 
| 460                                           HandleSignalsState* signals_state) { |  | 
| 461   lock_.AssertAcquired(); |  | 
| 462   DCHECK(!is_closed_); |  | 
| 463   // By default, waiting isn't supported. Only dispatchers that can be waited on |  | 
| 464   // will do something nontrivial. |  | 
| 465   if (signals_state) |  | 
| 466     *signals_state = HandleSignalsState(); |  | 
| 467 } |  | 
| 468 |  | 
| 469 void Dispatcher::StartSerializeImplNoLock(size_t* max_size, |  | 
| 470                                           size_t* max_platform_handles) { |  | 
| 471   DCHECK(!is_closed_); |  | 
| 472   *max_size = 0; |  | 
| 473   *max_platform_handles = 0; |  | 
| 474 } |  | 
| 475 |  | 
| 476 bool Dispatcher::EndSerializeAndCloseImplNoLock( |  | 
| 477     void* /*destination*/, |  | 
| 478     size_t* /*actual_size*/, |  | 
| 479     PlatformHandleVector* /*platform_handles*/) { |  | 
| 480   DCHECK(is_closed_); |  | 
| 481   // By default, serializing isn't supported, so just close. |  | 
| 482   CloseImplNoLock(); |  | 
| 483   return false; |  | 
| 484 } |  | 
| 485 |  | 
| 486 bool Dispatcher::IsBusyNoLock() const { |  | 
| 487   lock_.AssertAcquired(); |  | 
| 488   DCHECK(!is_closed_); |  | 
| 489   // Most dispatchers support only "atomic" operations, so they are never busy |  | 
| 490   // (in this sense). |  | 
| 491   return false; |  | 
| 492 } |  | 
| 493 |  | 
| 494 void Dispatcher::CloseNoLock() { |  | 
| 495   lock_.AssertAcquired(); |  | 
| 496   DCHECK(!is_closed_); |  | 
| 497 |  | 
| 498   is_closed_ = true; |  | 
| 499   CancelAllAwakablesNoLock(); |  | 
| 500   CloseImplNoLock(); |  | 
| 501 } |  | 
| 502 |  | 
| 503 scoped_refptr<Dispatcher> |  | 
| 504 Dispatcher::CreateEquivalentDispatcherAndCloseNoLock() { |  | 
| 505   lock_.AssertAcquired(); |  | 
| 506   DCHECK(!is_closed_); |  | 
| 507 |  | 
| 508   is_closed_ = true; |  | 
| 509   CancelAllAwakablesNoLock(); |  | 
| 510   return CreateEquivalentDispatcherAndCloseImplNoLock(); |  | 
| 511 } |  | 
| 512 |  | 
| 513 void Dispatcher::StartSerialize(size_t* max_size, |  | 
| 514                                 size_t* max_platform_handles) { |  | 
| 515   DCHECK(max_size); |  | 
| 516   DCHECK(max_platform_handles); |  | 
| 517   DCHECK(!is_closed_); |  | 
| 518   base::AutoLock locker(lock_); |  | 
| 519   StartSerializeImplNoLock(max_size, max_platform_handles); |  | 
| 520 } |  | 
| 521 |  | 
| 522 bool Dispatcher::EndSerializeAndClose(void* destination, |  | 
| 523                                       size_t* actual_size, |  | 
| 524                                       PlatformHandleVector* platform_handles) { |  | 
| 525   DCHECK(actual_size); |  | 
| 526   DCHECK(!is_closed_); |  | 
| 527 |  | 
| 528   // Like other |...Close()| methods, we mark ourselves as closed before calling |  | 
| 529   // the impl. But there's no need to cancel waiters: we shouldn't have any (and |  | 
| 530   // shouldn't be in |Core|'s handle table. |  | 
| 531   is_closed_ = true; |  | 
| 532 |  | 
| 533   base::AutoLock locker(lock_); |  | 
| 534   return EndSerializeAndCloseImplNoLock(destination, actual_size, |  | 
| 535                                         platform_handles); |  | 
| 536 } |  | 
| 537 |  | 
| 538 // DispatcherTransport --------------------------------------------------------- |  | 
| 539 |  | 
| 540 void DispatcherTransport::End() { |  | 
| 541   DCHECK(dispatcher_); |  | 
| 542   dispatcher_->lock_.Release(); |  | 
| 543 |  | 
| 544   dispatcher_->TransportEnded(); |  | 
| 545 |  | 
| 546   dispatcher_ = nullptr; |  | 
| 547 } |  | 
| 548 | 179 | 
| 549 }  // namespace edk | 180 }  // namespace edk | 
| 550 }  // namespace mojo | 181 }  // namespace mojo | 
| OLD | NEW | 
|---|