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