| 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/core.h" | 5 #include "mojo/edk/system/core.h" |
| 6 | 6 |
| 7 #include <string.h> | 7 #include <string.h> |
| 8 | 8 |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 40 | 40 |
| 41 namespace { | 41 namespace { |
| 42 | 42 |
| 43 // This is an unnecessarily large limit that is relatively easy to enforce. | 43 // This is an unnecessarily large limit that is relatively easy to enforce. |
| 44 const uint32_t kMaxHandlesPerMessage = 1024 * 1024; | 44 const uint32_t kMaxHandlesPerMessage = 1024 * 1024; |
| 45 | 45 |
| 46 // TODO: Maybe we could negotiate a debugging pipe ID for cross-process pipes | 46 // TODO: Maybe we could negotiate a debugging pipe ID for cross-process pipes |
| 47 // too; for now we just use a constant. This only affects bootstrap pipes. | 47 // too; for now we just use a constant. This only affects bootstrap pipes. |
| 48 const uint64_t kUnknownPipeIdForDebug = 0x7f7f7f7f7f7f7f7fUL; | 48 const uint64_t kUnknownPipeIdForDebug = 0x7f7f7f7f7f7f7f7fUL; |
| 49 | 49 |
| 50 void CallWatchCallback(MojoWatchCallback callback, |
| 51 uintptr_t context, |
| 52 MojoResult result, |
| 53 MojoHandleSignalsState signals_state) { |
| 54 callback(context, result, signals_state); |
| 55 } |
| 56 |
| 50 } // namespace | 57 } // namespace |
| 51 | 58 |
| 52 Core::Core() {} | 59 Core::Core() {} |
| 53 | 60 |
| 54 Core::~Core() { | 61 Core::~Core() { |
| 55 if (node_controller_ && node_controller_->io_task_runner()) { | 62 if (node_controller_ && node_controller_->io_task_runner()) { |
| 56 // If this races with IO thread shutdown the callback will be dropped and | 63 // If this races with IO thread shutdown the callback will be dropped and |
| 57 // the NodeController will be shutdown on this thread anyway, which is also | 64 // the NodeController will be shutdown on this thread anyway, which is also |
| 58 // just fine. | 65 // just fine. |
| 59 scoped_refptr<base::TaskRunner> io_task_runner = | 66 scoped_refptr<base::TaskRunner> io_task_runner = |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 98 bool Core::AddDispatchersFromTransit( | 105 bool Core::AddDispatchersFromTransit( |
| 99 const std::vector<Dispatcher::DispatcherInTransit>& dispatchers, | 106 const std::vector<Dispatcher::DispatcherInTransit>& dispatchers, |
| 100 MojoHandle* handles) { | 107 MojoHandle* handles) { |
| 101 bool failed = false; | 108 bool failed = false; |
| 102 { | 109 { |
| 103 base::AutoLock lock(handles_lock_); | 110 base::AutoLock lock(handles_lock_); |
| 104 if (!handles_.AddDispatchersFromTransit(dispatchers, handles)) | 111 if (!handles_.AddDispatchersFromTransit(dispatchers, handles)) |
| 105 failed = true; | 112 failed = true; |
| 106 } | 113 } |
| 107 if (failed) { | 114 if (failed) { |
| 115 Dispatcher::RequestContext request_context; |
| 108 for (auto d : dispatchers) | 116 for (auto d : dispatchers) |
| 109 d.dispatcher->Close(); | 117 d.dispatcher->Close(&request_context); |
| 110 return false; | 118 return false; |
| 111 } | 119 } |
| 112 return true; | 120 return true; |
| 113 } | 121 } |
| 114 | 122 |
| 115 MojoResult Core::CreatePlatformHandleWrapper( | 123 MojoResult Core::CreatePlatformHandleWrapper( |
| 116 ScopedPlatformHandle platform_handle, | 124 ScopedPlatformHandle platform_handle, |
| 117 MojoHandle* wrapper_handle) { | 125 MojoHandle* wrapper_handle) { |
| 118 MojoHandle h = AddDispatcher( | 126 MojoHandle h = AddDispatcher( |
| 119 PlatformHandleDispatcher::Create(std::move(platform_handle))); | 127 PlatformHandleDispatcher::Create(std::move(platform_handle))); |
| 120 if (h == MOJO_HANDLE_INVALID) | 128 if (h == MOJO_HANDLE_INVALID) |
| 121 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 129 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
| 122 *wrapper_handle = h; | 130 *wrapper_handle = h; |
| 123 return MOJO_RESULT_OK; | 131 return MOJO_RESULT_OK; |
| 124 } | 132 } |
| 125 | 133 |
| 126 MojoResult Core::PassWrappedPlatformHandle( | 134 MojoResult Core::PassWrappedPlatformHandle( |
| 127 MojoHandle wrapper_handle, | 135 MojoHandle wrapper_handle, |
| 128 ScopedPlatformHandle* platform_handle) { | 136 ScopedPlatformHandle* platform_handle) { |
| 129 base::AutoLock lock(handles_lock_); | 137 base::AutoLock lock(handles_lock_); |
| 130 scoped_refptr<Dispatcher> d; | 138 scoped_refptr<Dispatcher> d; |
| 131 MojoResult result = handles_.GetAndRemoveDispatcher(wrapper_handle, &d); | 139 MojoResult result = handles_.GetAndRemoveDispatcher(wrapper_handle, &d); |
| 132 if (result != MOJO_RESULT_OK) | 140 if (result != MOJO_RESULT_OK) |
| 133 return result; | 141 return result; |
| 134 PlatformHandleDispatcher* phd = | 142 PlatformHandleDispatcher* phd = |
| 135 static_cast<PlatformHandleDispatcher*>(d.get()); | 143 static_cast<PlatformHandleDispatcher*>(d.get()); |
| 136 *platform_handle = phd->PassPlatformHandle(); | 144 *platform_handle = phd->PassPlatformHandle(); |
| 137 phd->Close(); | 145 |
| 146 Dispatcher::RequestContext request_context; |
| 147 phd->Close(&request_context); |
| 148 |
| 138 return MOJO_RESULT_OK; | 149 return MOJO_RESULT_OK; |
| 139 } | 150 } |
| 140 | 151 |
| 141 MojoResult Core::CreateSharedBufferWrapper( | 152 MojoResult Core::CreateSharedBufferWrapper( |
| 142 base::SharedMemoryHandle shared_memory_handle, | 153 base::SharedMemoryHandle shared_memory_handle, |
| 143 size_t num_bytes, | 154 size_t num_bytes, |
| 144 bool read_only, | 155 bool read_only, |
| 145 MojoHandle* mojo_wrapper_handle) { | 156 MojoHandle* mojo_wrapper_handle) { |
| 146 DCHECK(num_bytes); | 157 DCHECK(num_bytes); |
| 147 CHECK(!read_only); | 158 CHECK(!read_only); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 194 | 205 |
| 195 if (!platform_shared_buffer) | 206 if (!platform_shared_buffer) |
| 196 return MOJO_RESULT_INVALID_ARGUMENT; | 207 return MOJO_RESULT_INVALID_ARGUMENT; |
| 197 | 208 |
| 198 if (num_bytes) | 209 if (num_bytes) |
| 199 *num_bytes = platform_shared_buffer->GetNumBytes(); | 210 *num_bytes = platform_shared_buffer->GetNumBytes(); |
| 200 if (read_only) | 211 if (read_only) |
| 201 *read_only = false; | 212 *read_only = false; |
| 202 *shared_memory_handle = platform_shared_buffer->DuplicateSharedMemoryHandle(); | 213 *shared_memory_handle = platform_shared_buffer->DuplicateSharedMemoryHandle(); |
| 203 | 214 |
| 204 shm_dispatcher->Close(); | 215 Dispatcher::RequestContext request_context; |
| 216 shm_dispatcher->Close(&request_context); |
| 217 |
| 205 return result; | 218 return result; |
| 206 } | 219 } |
| 207 | 220 |
| 208 void Core::RequestShutdown(const base::Closure& callback) { | 221 void Core::RequestShutdown(const base::Closure& callback) { |
| 209 base::Closure on_shutdown; | 222 base::Closure on_shutdown; |
| 210 if (base::ThreadTaskRunnerHandle::IsSet()) { | 223 if (base::ThreadTaskRunnerHandle::IsSet()) { |
| 211 on_shutdown = base::Bind(base::IgnoreResult(&base::TaskRunner::PostTask), | 224 on_shutdown = base::Bind(base::IgnoreResult(&base::TaskRunner::PostTask), |
| 212 base::ThreadTaskRunnerHandle::Get(), | 225 base::ThreadTaskRunnerHandle::Get(), |
| 213 FROM_HERE, callback); | 226 FROM_HERE, callback); |
| 214 } else { | 227 } else { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 268 } | 281 } |
| 269 | 282 |
| 270 MojoResult Core::Close(MojoHandle handle) { | 283 MojoResult Core::Close(MojoHandle handle) { |
| 271 scoped_refptr<Dispatcher> dispatcher; | 284 scoped_refptr<Dispatcher> dispatcher; |
| 272 { | 285 { |
| 273 base::AutoLock lock(handles_lock_); | 286 base::AutoLock lock(handles_lock_); |
| 274 MojoResult rv = handles_.GetAndRemoveDispatcher(handle, &dispatcher); | 287 MojoResult rv = handles_.GetAndRemoveDispatcher(handle, &dispatcher); |
| 275 if (rv != MOJO_RESULT_OK) | 288 if (rv != MOJO_RESULT_OK) |
| 276 return rv; | 289 return rv; |
| 277 } | 290 } |
| 278 dispatcher->Close(); | 291 |
| 292 Dispatcher::RequestContext request_context; |
| 293 dispatcher->Close(&request_context); |
| 279 return MOJO_RESULT_OK; | 294 return MOJO_RESULT_OK; |
| 280 } | 295 } |
| 281 | 296 |
| 282 MojoResult Core::Wait(MojoHandle handle, | 297 MojoResult Core::Wait(MojoHandle handle, |
| 283 MojoHandleSignals signals, | 298 MojoHandleSignals signals, |
| 284 MojoDeadline deadline, | 299 MojoDeadline deadline, |
| 285 MojoHandleSignalsState* signals_state) { | 300 MojoHandleSignalsState* signals_state) { |
| 286 uint32_t unused = static_cast<uint32_t>(-1); | 301 uint32_t unused = static_cast<uint32_t>(-1); |
| 287 HandleSignalsState hss; | 302 HandleSignalsState hss; |
| 288 MojoResult rv = WaitManyInternal(&handle, &signals, 1, deadline, &unused, | 303 MojoResult rv = WaitManyInternal(&handle, &signals, 1, deadline, &unused, |
| (...skipping 23 matching lines...) Expand all Loading... |
| 312 // Note: The |reinterpret_cast| is safe, since |HandleSignalsState| is a | 327 // Note: The |reinterpret_cast| is safe, since |HandleSignalsState| is a |
| 313 // subclass of |MojoHandleSignalsState| that doesn't add any data members. | 328 // subclass of |MojoHandleSignalsState| that doesn't add any data members. |
| 314 rv = WaitManyInternal(handles, signals, num_handles, deadline, &index, | 329 rv = WaitManyInternal(handles, signals, num_handles, deadline, &index, |
| 315 reinterpret_cast<HandleSignalsState*>(signals_state)); | 330 reinterpret_cast<HandleSignalsState*>(signals_state)); |
| 316 } | 331 } |
| 317 if (index != static_cast<uint32_t>(-1) && result_index) | 332 if (index != static_cast<uint32_t>(-1) && result_index) |
| 318 *result_index = index; | 333 *result_index = index; |
| 319 return rv; | 334 return rv; |
| 320 } | 335 } |
| 321 | 336 |
| 337 MojoResult Core::Watch(MojoHandle handle, |
| 338 MojoHandleSignals signals, |
| 339 MojoWatchCallback callback, |
| 340 uintptr_t context) { |
| 341 scoped_refptr<Dispatcher> dispatcher = GetDispatcher(handle); |
| 342 if (!dispatcher) |
| 343 return MOJO_RESULT_INVALID_ARGUMENT; |
| 344 |
| 345 Dispatcher::RequestContext request_context; |
| 346 return dispatcher->Watch( |
| 347 signals, base::Bind(&CallWatchCallback, callback, context), context, |
| 348 &request_context); |
| 349 } |
| 350 |
| 351 MojoResult Core::CancelWatch(MojoHandle handle, uintptr_t context) { |
| 352 scoped_refptr<Dispatcher> dispatcher = GetDispatcher(handle); |
| 353 if (!dispatcher) |
| 354 return MOJO_RESULT_INVALID_ARGUMENT; |
| 355 return dispatcher->CancelWatch(context); |
| 356 } |
| 357 |
| 322 MojoResult Core::CreateWaitSet(MojoHandle* wait_set_handle) { | 358 MojoResult Core::CreateWaitSet(MojoHandle* wait_set_handle) { |
| 323 if (!wait_set_handle) | 359 if (!wait_set_handle) |
| 324 return MOJO_RESULT_INVALID_ARGUMENT; | 360 return MOJO_RESULT_INVALID_ARGUMENT; |
| 325 | 361 |
| 326 scoped_refptr<WaitSetDispatcher> dispatcher = new WaitSetDispatcher(); | 362 scoped_refptr<WaitSetDispatcher> dispatcher = new WaitSetDispatcher(); |
| 327 MojoHandle h = AddDispatcher(dispatcher); | 363 MojoHandle h = AddDispatcher(dispatcher); |
| 328 if (h == MOJO_HANDLE_INVALID) { | 364 if (h == MOJO_HANDLE_INVALID) { |
| 329 LOG(ERROR) << "Handle table full"; | 365 LOG(ERROR) << "Handle table full"; |
| 330 dispatcher->Close(); | 366 Dispatcher::RequestContext request_context; |
| 367 dispatcher->Close(&request_context); |
| 331 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 368 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
| 332 } | 369 } |
| 333 | 370 |
| 334 *wait_set_handle = h; | 371 *wait_set_handle = h; |
| 335 return MOJO_RESULT_OK; | 372 return MOJO_RESULT_OK; |
| 336 } | 373 } |
| 337 | 374 |
| 338 MojoResult Core::AddHandle(MojoHandle wait_set_handle, | 375 MojoResult Core::AddHandle(MojoHandle wait_set_handle, |
| 339 MojoHandle handle, | 376 MojoHandle handle, |
| 340 MojoHandleSignals signals) { | 377 MojoHandleSignals signals) { |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 405 uint64_t pipe_id = base::RandUint64(); | 442 uint64_t pipe_id = base::RandUint64(); |
| 406 | 443 |
| 407 *message_pipe_handle0 = AddDispatcher( | 444 *message_pipe_handle0 = AddDispatcher( |
| 408 new MessagePipeDispatcher(GetNodeController(), port0, pipe_id, 0)); | 445 new MessagePipeDispatcher(GetNodeController(), port0, pipe_id, 0)); |
| 409 if (*message_pipe_handle0 == MOJO_HANDLE_INVALID) | 446 if (*message_pipe_handle0 == MOJO_HANDLE_INVALID) |
| 410 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 447 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
| 411 | 448 |
| 412 *message_pipe_handle1 = AddDispatcher( | 449 *message_pipe_handle1 = AddDispatcher( |
| 413 new MessagePipeDispatcher(GetNodeController(), port1, pipe_id, 1)); | 450 new MessagePipeDispatcher(GetNodeController(), port1, pipe_id, 1)); |
| 414 if (*message_pipe_handle1 == MOJO_HANDLE_INVALID) { | 451 if (*message_pipe_handle1 == MOJO_HANDLE_INVALID) { |
| 452 Dispatcher::RequestContext request_context; |
| 415 scoped_refptr<Dispatcher> unused; | 453 scoped_refptr<Dispatcher> unused; |
| 416 unused->Close(); | 454 unused->Close(&request_context); |
| 417 handles_.GetAndRemoveDispatcher(*message_pipe_handle0, &unused); | 455 handles_.GetAndRemoveDispatcher(*message_pipe_handle0, &unused); |
| 418 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 456 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
| 419 } | 457 } |
| 420 | 458 |
| 421 return MOJO_RESULT_OK; | 459 return MOJO_RESULT_OK; |
| 422 } | 460 } |
| 423 | 461 |
| 424 MojoResult Core::WriteMessage(MojoHandle message_pipe_handle, | 462 MojoResult Core::WriteMessage(MojoHandle message_pipe_handle, |
| 425 const void* bytes, | 463 const void* bytes, |
| 426 uint32_t num_bytes, | 464 uint32_t num_bytes, |
| 427 const MojoHandle* handles, | 465 const MojoHandle* handles, |
| 428 uint32_t num_handles, | 466 uint32_t num_handles, |
| 429 MojoWriteMessageFlags flags) { | 467 MojoWriteMessageFlags flags) { |
| 430 auto dispatcher = GetDispatcher(message_pipe_handle); | 468 auto dispatcher = GetDispatcher(message_pipe_handle); |
| 431 if (!dispatcher) | 469 if (!dispatcher) |
| 432 return MOJO_RESULT_INVALID_ARGUMENT; | 470 return MOJO_RESULT_INVALID_ARGUMENT; |
| 433 | 471 |
| 434 if (num_handles == 0) // Fast path: no handles. | 472 Dispatcher::RequestContext request_context; |
| 435 return dispatcher->WriteMessage(bytes, num_bytes, nullptr, 0, flags); | 473 if (num_handles == 0) { |
| 474 // Fast path: no handles. |
| 475 return dispatcher->WriteMessage( |
| 476 bytes, num_bytes, nullptr, 0, flags, &request_context); |
| 477 } |
| 436 | 478 |
| 437 CHECK(handles); | 479 CHECK(handles); |
| 438 | 480 |
| 439 if (num_handles > kMaxHandlesPerMessage) | 481 if (num_handles > kMaxHandlesPerMessage) |
| 440 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 482 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
| 441 | 483 |
| 442 for (size_t i = 0; i < num_handles; ++i) { | 484 for (size_t i = 0; i < num_handles; ++i) { |
| 443 if (message_pipe_handle == handles[i]) | 485 if (message_pipe_handle == handles[i]) |
| 444 return MOJO_RESULT_BUSY; | 486 return MOJO_RESULT_BUSY; |
| 445 } | 487 } |
| 446 | 488 |
| 447 std::vector<Dispatcher::DispatcherInTransit> dispatchers; | 489 std::vector<Dispatcher::DispatcherInTransit> dispatchers; |
| 448 { | 490 { |
| 449 base::AutoLock lock(handles_lock_); | 491 base::AutoLock lock(handles_lock_); |
| 450 MojoResult rv = handles_.BeginTransit(handles, num_handles, &dispatchers); | 492 MojoResult rv = handles_.BeginTransit( |
| 493 handles, num_handles, &dispatchers, &request_context); |
| 451 if (rv != MOJO_RESULT_OK) { | 494 if (rv != MOJO_RESULT_OK) { |
| 452 handles_.CancelTransit(dispatchers); | 495 handles_.CancelTransit(dispatchers, &request_context); |
| 453 return rv; | 496 return rv; |
| 454 } | 497 } |
| 455 } | 498 } |
| 456 DCHECK_EQ(num_handles, dispatchers.size()); | 499 DCHECK_EQ(num_handles, dispatchers.size()); |
| 457 | 500 |
| 458 MojoResult rv = dispatcher->WriteMessage( | 501 MojoResult rv = dispatcher->WriteMessage( |
| 459 bytes, num_bytes, dispatchers.data(), num_handles, flags); | 502 bytes, num_bytes, dispatchers.data(), num_handles, flags, |
| 503 &request_context); |
| 460 | 504 |
| 461 { | 505 { |
| 462 base::AutoLock lock(handles_lock_); | 506 base::AutoLock lock(handles_lock_); |
| 463 if (rv == MOJO_RESULT_OK) { | 507 if (rv == MOJO_RESULT_OK) { |
| 464 handles_.CompleteTransitAndClose(dispatchers); | 508 handles_.CompleteTransitAndClose(dispatchers, &request_context); |
| 465 } else { | 509 } else { |
| 466 handles_.CancelTransit(dispatchers); | 510 handles_.CancelTransit(dispatchers, &request_context); |
| 467 } | 511 } |
| 468 } | 512 } |
| 469 | 513 |
| 470 return rv; | 514 return rv; |
| 471 } | 515 } |
| 472 | 516 |
| 473 MojoResult Core::ReadMessage(MojoHandle message_pipe_handle, | 517 MojoResult Core::ReadMessage(MojoHandle message_pipe_handle, |
| 474 void* bytes, | 518 void* bytes, |
| 475 uint32_t* num_bytes, | 519 uint32_t* num_bytes, |
| 476 MojoHandle* handles, | 520 MojoHandle* handles, |
| 477 uint32_t* num_handles, | 521 uint32_t* num_handles, |
| 478 MojoReadMessageFlags flags) { | 522 MojoReadMessageFlags flags) { |
| 479 CHECK((!num_handles || !*num_handles || handles) && | 523 CHECK((!num_handles || !*num_handles || handles) && |
| 480 (!num_bytes || !*num_bytes || bytes)); | 524 (!num_bytes || !*num_bytes || bytes)); |
| 481 auto dispatcher = GetDispatcher(message_pipe_handle); | 525 auto dispatcher = GetDispatcher(message_pipe_handle); |
| 482 if (!dispatcher) | 526 if (!dispatcher) |
| 483 return MOJO_RESULT_INVALID_ARGUMENT; | 527 return MOJO_RESULT_INVALID_ARGUMENT; |
| 484 return dispatcher->ReadMessage(bytes, num_bytes, handles, num_handles, flags); | 528 Dispatcher::RequestContext request_context; |
| 529 return dispatcher->ReadMessage( |
| 530 bytes, num_bytes, handles, num_handles, flags, &request_context); |
| 485 } | 531 } |
| 486 | 532 |
| 487 MojoResult Core::CreateDataPipe( | 533 MojoResult Core::CreateDataPipe( |
| 488 const MojoCreateDataPipeOptions* options, | 534 const MojoCreateDataPipeOptions* options, |
| 489 MojoHandle* data_pipe_producer_handle, | 535 MojoHandle* data_pipe_producer_handle, |
| 490 MojoHandle* data_pipe_consumer_handle) { | 536 MojoHandle* data_pipe_consumer_handle) { |
| 491 if (options && options->struct_size != sizeof(MojoCreateDataPipeOptions)) | 537 if (options && options->struct_size != sizeof(MojoCreateDataPipeOptions)) |
| 492 return MOJO_RESULT_INVALID_ARGUMENT; | 538 return MOJO_RESULT_INVALID_ARGUMENT; |
| 493 | 539 |
| 494 MojoCreateDataPipeOptions create_options; | 540 MojoCreateDataPipeOptions create_options; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 523 true /* initialized */, pipe_id); | 569 true /* initialized */, pipe_id); |
| 524 | 570 |
| 525 *data_pipe_producer_handle = AddDispatcher(producer); | 571 *data_pipe_producer_handle = AddDispatcher(producer); |
| 526 *data_pipe_consumer_handle = AddDispatcher(consumer); | 572 *data_pipe_consumer_handle = AddDispatcher(consumer); |
| 527 if (*data_pipe_producer_handle == MOJO_HANDLE_INVALID || | 573 if (*data_pipe_producer_handle == MOJO_HANDLE_INVALID || |
| 528 *data_pipe_consumer_handle == MOJO_HANDLE_INVALID) { | 574 *data_pipe_consumer_handle == MOJO_HANDLE_INVALID) { |
| 529 if (*data_pipe_producer_handle != MOJO_HANDLE_INVALID) { | 575 if (*data_pipe_producer_handle != MOJO_HANDLE_INVALID) { |
| 530 scoped_refptr<Dispatcher> unused; | 576 scoped_refptr<Dispatcher> unused; |
| 531 handles_.GetAndRemoveDispatcher(*data_pipe_producer_handle, &unused); | 577 handles_.GetAndRemoveDispatcher(*data_pipe_producer_handle, &unused); |
| 532 } | 578 } |
| 533 producer->Close(); | 579 |
| 534 consumer->Close(); | 580 Dispatcher::RequestContext request_context; |
| 581 producer->Close(&request_context); |
| 582 consumer->Close(&request_context); |
| 535 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 583 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
| 536 } | 584 } |
| 537 | 585 |
| 538 return MOJO_RESULT_OK; | 586 return MOJO_RESULT_OK; |
| 539 } | 587 } |
| 540 | 588 |
| 541 MojoResult Core::WriteData(MojoHandle data_pipe_producer_handle, | 589 MojoResult Core::WriteData(MojoHandle data_pipe_producer_handle, |
| 542 const void* elements, | 590 const void* elements, |
| 543 uint32_t* num_bytes, | 591 uint32_t* num_bytes, |
| 544 MojoWriteDataFlags flags) { | 592 MojoWriteDataFlags flags) { |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 620 result = | 668 result = |
| 621 SharedBufferDispatcher::Create(validated_options, num_bytes, &dispatcher); | 669 SharedBufferDispatcher::Create(validated_options, num_bytes, &dispatcher); |
| 622 if (result != MOJO_RESULT_OK) { | 670 if (result != MOJO_RESULT_OK) { |
| 623 DCHECK(!dispatcher); | 671 DCHECK(!dispatcher); |
| 624 return result; | 672 return result; |
| 625 } | 673 } |
| 626 | 674 |
| 627 *shared_buffer_handle = AddDispatcher(dispatcher); | 675 *shared_buffer_handle = AddDispatcher(dispatcher); |
| 628 if (*shared_buffer_handle == MOJO_HANDLE_INVALID) { | 676 if (*shared_buffer_handle == MOJO_HANDLE_INVALID) { |
| 629 LOG(ERROR) << "Handle table full"; | 677 LOG(ERROR) << "Handle table full"; |
| 630 dispatcher->Close(); | 678 Dispatcher::RequestContext request_context; |
| 679 dispatcher->Close(&request_context); |
| 631 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 680 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
| 632 } | 681 } |
| 633 | 682 |
| 634 return MOJO_RESULT_OK; | 683 return MOJO_RESULT_OK; |
| 635 } | 684 } |
| 636 | 685 |
| 637 MojoResult Core::DuplicateBufferHandle( | 686 MojoResult Core::DuplicateBufferHandle( |
| 638 MojoHandle buffer_handle, | 687 MojoHandle buffer_handle, |
| 639 const MojoDuplicateBufferHandleOptions* options, | 688 const MojoDuplicateBufferHandleOptions* options, |
| 640 MojoHandle* new_buffer_handle) { | 689 MojoHandle* new_buffer_handle) { |
| 641 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(buffer_handle)); | 690 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(buffer_handle)); |
| 642 if (!dispatcher) | 691 if (!dispatcher) |
| 643 return MOJO_RESULT_INVALID_ARGUMENT; | 692 return MOJO_RESULT_INVALID_ARGUMENT; |
| 644 | 693 |
| 645 // Don't verify |options| here; that's the dispatcher's job. | 694 // Don't verify |options| here; that's the dispatcher's job. |
| 646 scoped_refptr<Dispatcher> new_dispatcher; | 695 scoped_refptr<Dispatcher> new_dispatcher; |
| 647 MojoResult result = | 696 MojoResult result = |
| 648 dispatcher->DuplicateBufferHandle(options, &new_dispatcher); | 697 dispatcher->DuplicateBufferHandle(options, &new_dispatcher); |
| 649 if (result != MOJO_RESULT_OK) | 698 if (result != MOJO_RESULT_OK) |
| 650 return result; | 699 return result; |
| 651 | 700 |
| 652 *new_buffer_handle = AddDispatcher(new_dispatcher); | 701 *new_buffer_handle = AddDispatcher(new_dispatcher); |
| 653 if (*new_buffer_handle == MOJO_HANDLE_INVALID) { | 702 if (*new_buffer_handle == MOJO_HANDLE_INVALID) { |
| 654 LOG(ERROR) << "Handle table full"; | 703 LOG(ERROR) << "Handle table full"; |
| 655 dispatcher->Close(); | 704 Dispatcher::RequestContext request_context; |
| 705 dispatcher->Close(&request_context); |
| 656 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 706 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
| 657 } | 707 } |
| 658 | 708 |
| 659 return MOJO_RESULT_OK; | 709 return MOJO_RESULT_OK; |
| 660 } | 710 } |
| 661 | 711 |
| 662 MojoResult Core::MapBuffer(MojoHandle buffer_handle, | 712 MojoResult Core::MapBuffer(MojoHandle buffer_handle, |
| 663 uint64_t offset, | 713 uint64_t offset, |
| 664 uint64_t num_bytes, | 714 uint64_t num_bytes, |
| 665 void** buffer, | 715 void** buffer, |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 769 scoped_ptr<NodeController> node_controller) { | 819 scoped_ptr<NodeController> node_controller) { |
| 770 // It's OK to leak this reference. At this point we know the IO loop is still | 820 // It's OK to leak this reference. At this point we know the IO loop is still |
| 771 // running, and we know the NodeController will observe its eventual | 821 // running, and we know the NodeController will observe its eventual |
| 772 // destruction. This tells the NodeController to delete itself when that | 822 // destruction. This tells the NodeController to delete itself when that |
| 773 // happens. | 823 // happens. |
| 774 node_controller.release()->DestroyOnIOThreadShutdown(); | 824 node_controller.release()->DestroyOnIOThreadShutdown(); |
| 775 } | 825 } |
| 776 | 826 |
| 777 } // namespace edk | 827 } // namespace edk |
| 778 } // namespace mojo | 828 } // namespace mojo |
| OLD | NEW |