| 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 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 145 } | 145 } |
| 146 | 146 |
| 147 NodeController* Core::GetNodeController() { | 147 NodeController* Core::GetNodeController() { |
| 148 base::AutoLock lock(node_controller_lock_); | 148 base::AutoLock lock(node_controller_lock_); |
| 149 if (!node_controller_) | 149 if (!node_controller_) |
| 150 node_controller_.reset(new NodeController(this)); | 150 node_controller_.reset(new NodeController(this)); |
| 151 return node_controller_.get(); | 151 return node_controller_.get(); |
| 152 } | 152 } |
| 153 | 153 |
| 154 scoped_refptr<Dispatcher> Core::GetDispatcher(MojoHandle handle) { | 154 scoped_refptr<Dispatcher> Core::GetDispatcher(MojoHandle handle) { |
| 155 base::AutoLock lock(handles_lock_); | 155 base::AutoLock lock(handles_.GetLock()); |
| 156 return handles_.GetDispatcher(handle); | 156 return handles_.GetDispatcher(handle); |
| 157 } | 157 } |
| 158 | 158 |
| 159 void Core::SetDefaultProcessErrorCallback( | 159 void Core::SetDefaultProcessErrorCallback( |
| 160 const ProcessErrorCallback& callback) { | 160 const ProcessErrorCallback& callback) { |
| 161 default_process_error_callback_ = callback; | 161 default_process_error_callback_ = callback; |
| 162 } | 162 } |
| 163 | 163 |
| 164 ScopedMessagePipeHandle Core::CreatePartialMessagePipe(ports::PortRef* peer) { | 164 ScopedMessagePipeHandle Core::CreatePartialMessagePipe(ports::PortRef* peer) { |
| 165 RequestContext request_context; | 165 RequestContext request_context; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 201 GetNodeController()->ClosePeerConnection(peer_connection_id); | 201 GetNodeController()->ClosePeerConnection(peer_connection_id); |
| 202 } | 202 } |
| 203 | 203 |
| 204 void Core::SetMachPortProvider(base::PortProvider* port_provider) { | 204 void Core::SetMachPortProvider(base::PortProvider* port_provider) { |
| 205 #if defined(OS_MACOSX) && !defined(OS_IOS) | 205 #if defined(OS_MACOSX) && !defined(OS_IOS) |
| 206 GetNodeController()->CreateMachPortRelay(port_provider); | 206 GetNodeController()->CreateMachPortRelay(port_provider); |
| 207 #endif | 207 #endif |
| 208 } | 208 } |
| 209 | 209 |
| 210 MojoHandle Core::AddDispatcher(scoped_refptr<Dispatcher> dispatcher) { | 210 MojoHandle Core::AddDispatcher(scoped_refptr<Dispatcher> dispatcher) { |
| 211 base::AutoLock lock(handles_lock_); | 211 base::AutoLock lock(handles_.GetLock()); |
| 212 return handles_.AddDispatcher(dispatcher); | 212 return handles_.AddDispatcher(dispatcher); |
| 213 } | 213 } |
| 214 | 214 |
| 215 bool Core::AddDispatchersFromTransit( | 215 bool Core::AddDispatchersFromTransit( |
| 216 const std::vector<Dispatcher::DispatcherInTransit>& dispatchers, | 216 const std::vector<Dispatcher::DispatcherInTransit>& dispatchers, |
| 217 MojoHandle* handles) { | 217 MojoHandle* handles) { |
| 218 bool failed = false; | 218 bool failed = false; |
| 219 { | 219 { |
| 220 base::AutoLock lock(handles_lock_); | 220 base::AutoLock lock(handles_.GetLock()); |
| 221 if (!handles_.AddDispatchersFromTransit(dispatchers, handles)) | 221 if (!handles_.AddDispatchersFromTransit(dispatchers, handles)) |
| 222 failed = true; | 222 failed = true; |
| 223 } | 223 } |
| 224 if (failed) { | 224 if (failed) { |
| 225 for (auto d : dispatchers) | 225 for (auto d : dispatchers) |
| 226 d.dispatcher->Close(); | 226 d.dispatcher->Close(); |
| 227 return false; | 227 return false; |
| 228 } | 228 } |
| 229 return true; | 229 return true; |
| 230 } | 230 } |
| 231 | 231 |
| 232 MojoResult Core::CreatePlatformHandleWrapper( | 232 MojoResult Core::CreatePlatformHandleWrapper( |
| 233 ScopedPlatformHandle platform_handle, | 233 ScopedPlatformHandle platform_handle, |
| 234 MojoHandle* wrapper_handle) { | 234 MojoHandle* wrapper_handle) { |
| 235 MojoHandle h = AddDispatcher( | 235 MojoHandle h = AddDispatcher( |
| 236 PlatformHandleDispatcher::Create(std::move(platform_handle))); | 236 PlatformHandleDispatcher::Create(std::move(platform_handle))); |
| 237 if (h == MOJO_HANDLE_INVALID) | 237 if (h == MOJO_HANDLE_INVALID) |
| 238 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 238 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
| 239 *wrapper_handle = h; | 239 *wrapper_handle = h; |
| 240 return MOJO_RESULT_OK; | 240 return MOJO_RESULT_OK; |
| 241 } | 241 } |
| 242 | 242 |
| 243 MojoResult Core::PassWrappedPlatformHandle( | 243 MojoResult Core::PassWrappedPlatformHandle( |
| 244 MojoHandle wrapper_handle, | 244 MojoHandle wrapper_handle, |
| 245 ScopedPlatformHandle* platform_handle) { | 245 ScopedPlatformHandle* platform_handle) { |
| 246 base::AutoLock lock(handles_lock_); | 246 base::AutoLock lock(handles_.GetLock()); |
| 247 scoped_refptr<Dispatcher> d; | 247 scoped_refptr<Dispatcher> d; |
| 248 MojoResult result = handles_.GetAndRemoveDispatcher(wrapper_handle, &d); | 248 MojoResult result = handles_.GetAndRemoveDispatcher(wrapper_handle, &d); |
| 249 if (result != MOJO_RESULT_OK) | 249 if (result != MOJO_RESULT_OK) |
| 250 return result; | 250 return result; |
| 251 if (d->GetType() == Dispatcher::Type::PLATFORM_HANDLE) { | 251 if (d->GetType() == Dispatcher::Type::PLATFORM_HANDLE) { |
| 252 PlatformHandleDispatcher* phd = | 252 PlatformHandleDispatcher* phd = |
| 253 static_cast<PlatformHandleDispatcher*>(d.get()); | 253 static_cast<PlatformHandleDispatcher*>(d.get()); |
| 254 *platform_handle = phd->PassPlatformHandle(); | 254 *platform_handle = phd->PassPlatformHandle(); |
| 255 } else { | 255 } else { |
| 256 result = MOJO_RESULT_INVALID_ARGUMENT; | 256 result = MOJO_RESULT_INVALID_ARGUMENT; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 287 MojoHandle mojo_handle, | 287 MojoHandle mojo_handle, |
| 288 base::SharedMemoryHandle* shared_memory_handle, | 288 base::SharedMemoryHandle* shared_memory_handle, |
| 289 size_t* num_bytes, | 289 size_t* num_bytes, |
| 290 bool* read_only) { | 290 bool* read_only) { |
| 291 if (!shared_memory_handle) | 291 if (!shared_memory_handle) |
| 292 return MOJO_RESULT_INVALID_ARGUMENT; | 292 return MOJO_RESULT_INVALID_ARGUMENT; |
| 293 | 293 |
| 294 scoped_refptr<Dispatcher> dispatcher; | 294 scoped_refptr<Dispatcher> dispatcher; |
| 295 MojoResult result = MOJO_RESULT_OK; | 295 MojoResult result = MOJO_RESULT_OK; |
| 296 { | 296 { |
| 297 base::AutoLock lock(handles_lock_); | 297 base::AutoLock lock(handles_.GetLock()); |
| 298 // Get the dispatcher and check it before removing it from the handle table | 298 // Get the dispatcher and check it before removing it from the handle table |
| 299 // to ensure that the dispatcher is of the correct type. This ensures we | 299 // to ensure that the dispatcher is of the correct type. This ensures we |
| 300 // don't close and remove the wrong type of dispatcher. | 300 // don't close and remove the wrong type of dispatcher. |
| 301 dispatcher = handles_.GetDispatcher(mojo_handle); | 301 dispatcher = handles_.GetDispatcher(mojo_handle); |
| 302 if (!dispatcher || dispatcher->GetType() != Dispatcher::Type::SHARED_BUFFER) | 302 if (!dispatcher || dispatcher->GetType() != Dispatcher::Type::SHARED_BUFFER) |
| 303 return MOJO_RESULT_INVALID_ARGUMENT; | 303 return MOJO_RESULT_INVALID_ARGUMENT; |
| 304 | 304 |
| 305 result = handles_.GetAndRemoveDispatcher(mojo_handle, &dispatcher); | 305 result = handles_.GetAndRemoveDispatcher(mojo_handle, &dispatcher); |
| 306 if (result != MOJO_RESULT_OK) | 306 if (result != MOJO_RESULT_OK) |
| 307 return result; | 307 return result; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 353 } | 353 } |
| 354 | 354 |
| 355 MojoTimeTicks Core::GetTimeTicksNow() { | 355 MojoTimeTicks Core::GetTimeTicksNow() { |
| 356 return base::TimeTicks::Now().ToInternalValue(); | 356 return base::TimeTicks::Now().ToInternalValue(); |
| 357 } | 357 } |
| 358 | 358 |
| 359 MojoResult Core::Close(MojoHandle handle) { | 359 MojoResult Core::Close(MojoHandle handle) { |
| 360 RequestContext request_context; | 360 RequestContext request_context; |
| 361 scoped_refptr<Dispatcher> dispatcher; | 361 scoped_refptr<Dispatcher> dispatcher; |
| 362 { | 362 { |
| 363 base::AutoLock lock(handles_lock_); | 363 base::AutoLock lock(handles_.GetLock()); |
| 364 MojoResult rv = handles_.GetAndRemoveDispatcher(handle, &dispatcher); | 364 MojoResult rv = handles_.GetAndRemoveDispatcher(handle, &dispatcher); |
| 365 if (rv != MOJO_RESULT_OK) | 365 if (rv != MOJO_RESULT_OK) |
| 366 return rv; | 366 return rv; |
| 367 } | 367 } |
| 368 dispatcher->Close(); | 368 dispatcher->Close(); |
| 369 return MOJO_RESULT_OK; | 369 return MOJO_RESULT_OK; |
| 370 } | 370 } |
| 371 | 371 |
| 372 MojoResult Core::QueryHandleSignalsState( | 372 MojoResult Core::QueryHandleSignalsState( |
| 373 MojoHandle handle, | 373 MojoHandle handle, |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 445 } | 445 } |
| 446 | 446 |
| 447 if (!handles) | 447 if (!handles) |
| 448 return MOJO_RESULT_INVALID_ARGUMENT; | 448 return MOJO_RESULT_INVALID_ARGUMENT; |
| 449 | 449 |
| 450 if (num_handles > kMaxHandlesPerMessage) | 450 if (num_handles > kMaxHandlesPerMessage) |
| 451 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 451 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
| 452 | 452 |
| 453 std::vector<Dispatcher::DispatcherInTransit> dispatchers; | 453 std::vector<Dispatcher::DispatcherInTransit> dispatchers; |
| 454 { | 454 { |
| 455 base::AutoLock lock(handles_lock_); | 455 base::AutoLock lock(handles_.GetLock()); |
| 456 MojoResult rv = handles_.BeginTransit(handles, num_handles, &dispatchers); | 456 MojoResult rv = handles_.BeginTransit(handles, num_handles, &dispatchers); |
| 457 if (rv != MOJO_RESULT_OK) { | 457 if (rv != MOJO_RESULT_OK) { |
| 458 handles_.CancelTransit(dispatchers); | 458 handles_.CancelTransit(dispatchers); |
| 459 return rv; | 459 return rv; |
| 460 } | 460 } |
| 461 } | 461 } |
| 462 DCHECK_EQ(num_handles, dispatchers.size()); | 462 DCHECK_EQ(num_handles, dispatchers.size()); |
| 463 | 463 |
| 464 std::unique_ptr<MessageForTransit> msg; | 464 std::unique_ptr<MessageForTransit> msg; |
| 465 MojoResult rv = MessageForTransit::Create( | 465 MojoResult rv = MessageForTransit::Create( |
| 466 &msg, num_bytes, dispatchers.data(), num_handles); | 466 &msg, num_bytes, dispatchers.data(), num_handles); |
| 467 | 467 |
| 468 { | 468 { |
| 469 base::AutoLock lock(handles_lock_); | 469 base::AutoLock lock(handles_.GetLock()); |
| 470 if (rv == MOJO_RESULT_OK) { | 470 if (rv == MOJO_RESULT_OK) { |
| 471 handles_.CompleteTransitAndClose(dispatchers); | 471 handles_.CompleteTransitAndClose(dispatchers); |
| 472 *message = reinterpret_cast<MojoMessageHandle>(msg.release()); | 472 *message = reinterpret_cast<MojoMessageHandle>(msg.release()); |
| 473 } else { | 473 } else { |
| 474 handles_.CancelTransit(dispatchers); | 474 handles_.CancelTransit(dispatchers); |
| 475 } | 475 } |
| 476 } | 476 } |
| 477 | 477 |
| 478 return rv; | 478 return rv; |
| 479 } | 479 } |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 524 new MessagePipeDispatcher(GetNodeController(), port0, pipe_id, 0)); | 524 new MessagePipeDispatcher(GetNodeController(), port0, pipe_id, 0)); |
| 525 if (*message_pipe_handle0 == MOJO_HANDLE_INVALID) | 525 if (*message_pipe_handle0 == MOJO_HANDLE_INVALID) |
| 526 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 526 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
| 527 | 527 |
| 528 *message_pipe_handle1 = AddDispatcher( | 528 *message_pipe_handle1 = AddDispatcher( |
| 529 new MessagePipeDispatcher(GetNodeController(), port1, pipe_id, 1)); | 529 new MessagePipeDispatcher(GetNodeController(), port1, pipe_id, 1)); |
| 530 if (*message_pipe_handle1 == MOJO_HANDLE_INVALID) { | 530 if (*message_pipe_handle1 == MOJO_HANDLE_INVALID) { |
| 531 scoped_refptr<Dispatcher> unused; | 531 scoped_refptr<Dispatcher> unused; |
| 532 unused->Close(); | 532 unused->Close(); |
| 533 | 533 |
| 534 base::AutoLock lock(handles_lock_); | 534 base::AutoLock lock(handles_.GetLock()); |
| 535 handles_.GetAndRemoveDispatcher(*message_pipe_handle0, &unused); | 535 handles_.GetAndRemoveDispatcher(*message_pipe_handle0, &unused); |
| 536 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 536 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
| 537 } | 537 } |
| 538 | 538 |
| 539 return MOJO_RESULT_OK; | 539 return MOJO_RESULT_OK; |
| 540 } | 540 } |
| 541 | 541 |
| 542 MojoResult Core::WriteMessage(MojoHandle message_pipe_handle, | 542 MojoResult Core::WriteMessage(MojoHandle message_pipe_handle, |
| 543 const void* bytes, | 543 const void* bytes, |
| 544 uint32_t num_bytes, | 544 uint32_t num_bytes, |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 624 return MOJO_RESULT_OK; | 624 return MOJO_RESULT_OK; |
| 625 } | 625 } |
| 626 | 626 |
| 627 MojoResult Core::FuseMessagePipes(MojoHandle handle0, MojoHandle handle1) { | 627 MojoResult Core::FuseMessagePipes(MojoHandle handle0, MojoHandle handle1) { |
| 628 RequestContext request_context; | 628 RequestContext request_context; |
| 629 scoped_refptr<Dispatcher> dispatcher0; | 629 scoped_refptr<Dispatcher> dispatcher0; |
| 630 scoped_refptr<Dispatcher> dispatcher1; | 630 scoped_refptr<Dispatcher> dispatcher1; |
| 631 | 631 |
| 632 bool valid_handles = true; | 632 bool valid_handles = true; |
| 633 { | 633 { |
| 634 base::AutoLock lock(handles_lock_); | 634 base::AutoLock lock(handles_.GetLock()); |
| 635 MojoResult result0 = handles_.GetAndRemoveDispatcher(handle0, &dispatcher0); | 635 MojoResult result0 = handles_.GetAndRemoveDispatcher(handle0, &dispatcher0); |
| 636 MojoResult result1 = handles_.GetAndRemoveDispatcher(handle1, &dispatcher1); | 636 MojoResult result1 = handles_.GetAndRemoveDispatcher(handle1, &dispatcher1); |
| 637 if (result0 != MOJO_RESULT_OK || result1 != MOJO_RESULT_OK || | 637 if (result0 != MOJO_RESULT_OK || result1 != MOJO_RESULT_OK || |
| 638 dispatcher0->GetType() != Dispatcher::Type::MESSAGE_PIPE || | 638 dispatcher0->GetType() != Dispatcher::Type::MESSAGE_PIPE || |
| 639 dispatcher1->GetType() != Dispatcher::Type::MESSAGE_PIPE) | 639 dispatcher1->GetType() != Dispatcher::Type::MESSAGE_PIPE) |
| 640 valid_handles = false; | 640 valid_handles = false; |
| 641 } | 641 } |
| 642 | 642 |
| 643 if (!valid_handles) { | 643 if (!valid_handles) { |
| 644 if (dispatcher0) | 644 if (dispatcher0) |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 720 producer->Close(); | 720 producer->Close(); |
| 721 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 721 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
| 722 } | 722 } |
| 723 | 723 |
| 724 *data_pipe_producer_handle = AddDispatcher(producer); | 724 *data_pipe_producer_handle = AddDispatcher(producer); |
| 725 *data_pipe_consumer_handle = AddDispatcher(consumer); | 725 *data_pipe_consumer_handle = AddDispatcher(consumer); |
| 726 if (*data_pipe_producer_handle == MOJO_HANDLE_INVALID || | 726 if (*data_pipe_producer_handle == MOJO_HANDLE_INVALID || |
| 727 *data_pipe_consumer_handle == MOJO_HANDLE_INVALID) { | 727 *data_pipe_consumer_handle == MOJO_HANDLE_INVALID) { |
| 728 if (*data_pipe_producer_handle != MOJO_HANDLE_INVALID) { | 728 if (*data_pipe_producer_handle != MOJO_HANDLE_INVALID) { |
| 729 scoped_refptr<Dispatcher> unused; | 729 scoped_refptr<Dispatcher> unused; |
| 730 base::AutoLock lock(handles_lock_); | 730 base::AutoLock lock(handles_.GetLock()); |
| 731 handles_.GetAndRemoveDispatcher(*data_pipe_producer_handle, &unused); | 731 handles_.GetAndRemoveDispatcher(*data_pipe_producer_handle, &unused); |
| 732 } | 732 } |
| 733 producer->Close(); | 733 producer->Close(); |
| 734 consumer->Close(); | 734 consumer->Close(); |
| 735 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 735 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
| 736 } | 736 } |
| 737 | 737 |
| 738 return MOJO_RESULT_OK; | 738 return MOJO_RESULT_OK; |
| 739 } | 739 } |
| 740 | 740 |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 959 } | 959 } |
| 960 | 960 |
| 961 MojoResult Core::UnwrapPlatformSharedBufferHandle( | 961 MojoResult Core::UnwrapPlatformSharedBufferHandle( |
| 962 MojoHandle mojo_handle, | 962 MojoHandle mojo_handle, |
| 963 MojoPlatformHandle* platform_handle, | 963 MojoPlatformHandle* platform_handle, |
| 964 size_t* size, | 964 size_t* size, |
| 965 MojoPlatformSharedBufferHandleFlags* flags) { | 965 MojoPlatformSharedBufferHandleFlags* flags) { |
| 966 scoped_refptr<Dispatcher> dispatcher; | 966 scoped_refptr<Dispatcher> dispatcher; |
| 967 MojoResult result = MOJO_RESULT_OK; | 967 MojoResult result = MOJO_RESULT_OK; |
| 968 { | 968 { |
| 969 base::AutoLock lock(handles_lock_); | 969 base::AutoLock lock(handles_.GetLock()); |
| 970 result = handles_.GetAndRemoveDispatcher(mojo_handle, &dispatcher); | 970 result = handles_.GetAndRemoveDispatcher(mojo_handle, &dispatcher); |
| 971 if (result != MOJO_RESULT_OK) | 971 if (result != MOJO_RESULT_OK) |
| 972 return result; | 972 return result; |
| 973 } | 973 } |
| 974 | 974 |
| 975 if (dispatcher->GetType() != Dispatcher::Type::SHARED_BUFFER) { | 975 if (dispatcher->GetType() != Dispatcher::Type::SHARED_BUFFER) { |
| 976 dispatcher->Close(); | 976 dispatcher->Close(); |
| 977 return MOJO_RESULT_INVALID_ARGUMENT; | 977 return MOJO_RESULT_INVALID_ARGUMENT; |
| 978 } | 978 } |
| 979 | 979 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 990 *flags = MOJO_PLATFORM_SHARED_BUFFER_HANDLE_FLAG_NONE; | 990 *flags = MOJO_PLATFORM_SHARED_BUFFER_HANDLE_FLAG_NONE; |
| 991 if (platform_shared_buffer->IsReadOnly()) | 991 if (platform_shared_buffer->IsReadOnly()) |
| 992 *flags |= MOJO_PLATFORM_SHARED_BUFFER_HANDLE_FLAG_READ_ONLY; | 992 *flags |= MOJO_PLATFORM_SHARED_BUFFER_HANDLE_FLAG_READ_ONLY; |
| 993 | 993 |
| 994 ScopedPlatformHandle handle = platform_shared_buffer->PassPlatformHandle(); | 994 ScopedPlatformHandle handle = platform_shared_buffer->PassPlatformHandle(); |
| 995 return ScopedPlatformHandleToMojoPlatformHandle(std::move(handle), | 995 return ScopedPlatformHandleToMojoPlatformHandle(std::move(handle), |
| 996 platform_handle); | 996 platform_handle); |
| 997 } | 997 } |
| 998 | 998 |
| 999 void Core::GetActiveHandlesForTest(std::vector<MojoHandle>* handles) { | 999 void Core::GetActiveHandlesForTest(std::vector<MojoHandle>* handles) { |
| 1000 base::AutoLock lock(handles_lock_); | 1000 base::AutoLock lock(handles_.GetLock()); |
| 1001 handles_.GetActiveHandlesForTest(handles); | 1001 handles_.GetActiveHandlesForTest(handles); |
| 1002 } | 1002 } |
| 1003 | 1003 |
| 1004 // static | 1004 // static |
| 1005 void Core::PassNodeControllerToIOThread( | 1005 void Core::PassNodeControllerToIOThread( |
| 1006 std::unique_ptr<NodeController> node_controller) { | 1006 std::unique_ptr<NodeController> node_controller) { |
| 1007 // It's OK to leak this reference. At this point we know the IO loop is still | 1007 // It's OK to leak this reference. At this point we know the IO loop is still |
| 1008 // running, and we know the NodeController will observe its eventual | 1008 // running, and we know the NodeController will observe its eventual |
| 1009 // destruction. This tells the NodeController to delete itself when that | 1009 // destruction. This tells the NodeController to delete itself when that |
| 1010 // happens. | 1010 // happens. |
| 1011 node_controller.release()->DestroyOnIOThreadShutdown(); | 1011 node_controller.release()->DestroyOnIOThreadShutdown(); |
| 1012 } | 1012 } |
| 1013 | 1013 |
| 1014 } // namespace edk | 1014 } // namespace edk |
| 1015 } // namespace mojo | 1015 } // namespace mojo |
| OLD | NEW |