OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "content/renderer/render_thread_impl.h" | 5 #include "content/renderer/render_thread_impl.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <limits> | 8 #include <limits> |
9 #include <map> | 9 #include <map> |
10 #include <utility> | 10 #include <utility> |
11 #include <vector> | 11 #include <vector> |
12 | 12 |
13 #include "base/allocator/allocator_extension.h" | 13 #include "base/allocator/allocator_extension.h" |
| 14 #include "base/at_exit.h" |
14 #include "base/command_line.h" | 15 #include "base/command_line.h" |
15 #include "base/debug/crash_logging.h" | 16 #include "base/debug/crash_logging.h" |
16 #include "base/lazy_instance.h" | 17 #include "base/lazy_instance.h" |
17 #include "base/logging.h" | 18 #include "base/logging.h" |
18 #include "base/macros.h" | 19 #include "base/macros.h" |
19 #include "base/memory/discardable_memory_allocator.h" | 20 #include "base/memory/discardable_memory_allocator.h" |
20 #include "base/memory/memory_coordinator_client_registry.h" | 21 #include "base/memory/memory_coordinator_client_registry.h" |
21 #include "base/memory/ptr_util.h" | 22 #include "base/memory/ptr_util.h" |
22 #include "base/memory/shared_memory.h" | 23 #include "base/memory/shared_memory.h" |
23 #include "base/metrics/field_trial.h" | 24 #include "base/metrics/field_trial.h" |
(...skipping 906 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
930 // TODO(fdoray): Remove this once the SequencedWorkerPool to TaskScheduler | 931 // TODO(fdoray): Remove this once the SequencedWorkerPool to TaskScheduler |
931 // redirection experiment concludes https://crbug.com/622400. | 932 // redirection experiment concludes https://crbug.com/622400. |
932 if (!command_line.HasSwitch(switches::kSingleProcess)) | 933 if (!command_line.HasSwitch(switches::kSingleProcess)) |
933 base::SequencedWorkerPool::EnableForProcess(); | 934 base::SequencedWorkerPool::EnableForProcess(); |
934 } | 935 } |
935 | 936 |
936 RenderThreadImpl::~RenderThreadImpl() { | 937 RenderThreadImpl::~RenderThreadImpl() { |
937 } | 938 } |
938 | 939 |
939 void RenderThreadImpl::Shutdown() { | 940 void RenderThreadImpl::Shutdown() { |
940 for (auto& observer : observers_) | 941 // In a multi-process mode, we immediately exit the renderer. |
941 observer.OnRenderProcessShutdown(); | 942 // Historically we had a graceful shutdown sequence here but it was |
| 943 // 1) a waste of performance and 2) a source of lots of complicated |
| 944 // crashes caused by shutdown ordering. Immediate exit eliminates |
| 945 // those problems. |
| 946 // |
| 947 // In a single-process mode, we cannot call _exit(0) in Shutdown() because |
| 948 // it will exit the process before the browser side is ready to exit. |
| 949 if (!base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 950 switches::kSingleProcess)) |
| 951 _exit(0); |
| 952 } |
942 | 953 |
943 if (memory_observer_) { | 954 bool RenderThreadImpl::ShouldBeDestroyed() { |
944 message_loop()->RemoveTaskObserver(memory_observer_.get()); | 955 DCHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( |
945 memory_observer_.reset(); | 956 switches::kSingleProcess)); |
946 } | 957 // In a single-process mode, it is unsafe to destruct this renderer thread |
947 | 958 // because we haven't run the shutdown sequence. Hence we leak the render |
948 // Wait for all databases to be closed. | 959 // thread. |
949 if (blink_platform_impl_) { | 960 // |
950 // Crash the process if they fail to close after a generous amount of time. | 961 // In this case, we also need to disable at-exit callbacks because some of |
951 bool all_closed = blink_platform_impl_->web_database_observer_impl() | 962 // the at-exit callbacks are expected to run after the renderer thread |
952 ->WaitForAllDatabasesToClose(base::TimeDelta::FromSeconds(60)); | 963 // has been destructed. |
953 CHECK(all_closed); | 964 base::AtExitManager::DisableAllAtExitManagers(); |
954 } | 965 return false; |
955 | |
956 // Shutdown in reverse of the initialization order. | |
957 if (devtools_agent_message_filter_.get()) { | |
958 RemoveFilter(devtools_agent_message_filter_.get()); | |
959 devtools_agent_message_filter_ = nullptr; | |
960 } | |
961 | |
962 RemoveFilter(audio_input_message_filter_.get()); | |
963 audio_input_message_filter_ = nullptr; | |
964 | |
965 #if BUILDFLAG(ENABLE_WEBRTC) | |
966 RTCPeerConnectionHandler::DestructAllHandlers(); | |
967 // |peer_connection_factory_| cannot be deleted until after the main message | |
968 // loop has been destroyed. This is because there may be pending tasks that | |
969 // hold on to objects produced by the PC factory that depend on threads owned | |
970 // by the PC factory. Once those tasks have been freed, the factory can be | |
971 // deleted. | |
972 #endif | |
973 vc_manager_.reset(); | |
974 | |
975 RemoveFilter(db_message_filter_.get()); | |
976 db_message_filter_ = nullptr; | |
977 | |
978 // Shutdown the file thread if it's running. | |
979 if (file_thread_) | |
980 file_thread_->Stop(); | |
981 | |
982 if (compositor_message_filter_.get()) { | |
983 RemoveFilter(compositor_message_filter_.get()); | |
984 compositor_message_filter_ = nullptr; | |
985 } | |
986 | |
987 #if defined(OS_ANDROID) | |
988 if (sync_compositor_message_filter_) { | |
989 RemoveFilter(sync_compositor_message_filter_.get()); | |
990 sync_compositor_message_filter_ = nullptr; | |
991 } | |
992 stream_texture_factory_ = nullptr; | |
993 #endif | |
994 | |
995 media_thread_.reset(); | |
996 | |
997 blink_platform_impl_->SetCompositorThread(nullptr); | |
998 | |
999 compositor_thread_.reset(); | |
1000 | |
1001 // AudioMessageFilter may be accessed on |media_thread_|, so shutdown after. | |
1002 RemoveFilter(audio_message_filter_.get()); | |
1003 audio_message_filter_ = nullptr; | |
1004 | |
1005 categorized_worker_pool_->Shutdown(); | |
1006 | |
1007 main_input_callback_.Cancel(); | |
1008 input_handler_manager_.reset(); | |
1009 if (input_event_filter_.get()) { | |
1010 RemoveFilter(input_event_filter_.get()); | |
1011 input_event_filter_ = nullptr; | |
1012 } | |
1013 | |
1014 // RemoveEmbeddedWorkerRoute may be called while deleting | |
1015 // EmbeddedWorkerDispatcher. So it must be deleted before deleting | |
1016 // RenderThreadImpl. | |
1017 embedded_worker_dispatcher_.reset(); | |
1018 | |
1019 // Ramp down IDB before we ramp down WebKit (and V8), since IDB classes might | |
1020 // hold pointers to V8 objects (e.g., via pending requests). | |
1021 main_thread_indexed_db_dispatcher_.reset(); | |
1022 | |
1023 main_thread_compositor_task_runner_ = nullptr; | |
1024 | |
1025 gpu_factories_.clear(); | |
1026 | |
1027 // Context providers must be released prior to destroying the GPU channel. | |
1028 shared_worker_context_provider_ = nullptr; | |
1029 shared_main_thread_contexts_ = nullptr; | |
1030 | |
1031 if (gpu_channel_.get()) | |
1032 gpu_channel_->DestroyChannel(); | |
1033 | |
1034 ChildThreadImpl::Shutdown(); | |
1035 | |
1036 // Shut down the message loop (if provided when the RenderThreadImpl was | |
1037 // constructed) and the renderer scheduler before shutting down Blink. This | |
1038 // prevents a scenario where a pending task in the message loop accesses Blink | |
1039 // objects after Blink shuts down. | |
1040 renderer_scheduler_->SetRAILModeObserver(nullptr); | |
1041 renderer_scheduler_->Shutdown(); | |
1042 if (main_message_loop_) | |
1043 base::RunLoop().RunUntilIdle(); | |
1044 | |
1045 if (blink_platform_impl_) { | |
1046 blink_platform_impl_->Shutdown(); | |
1047 // This must be at the very end of the shutdown sequence. | |
1048 // blink::shutdown() must be called after all strong references from | |
1049 // Chromium to Blink are cleared. | |
1050 blink::shutdown(); | |
1051 } | |
1052 | |
1053 // Delay shutting down DiscardableSharedMemoryManager until blink::shutdown | |
1054 // is complete, because blink::shutdown destructs Blink Resources and they | |
1055 // may try to unlock their underlying discardable memory. | |
1056 discardable_shared_memory_manager_.reset(); | |
1057 | |
1058 // The message loop must be cleared after shutting down | |
1059 // the DiscardableSharedMemoryManager, which needs to send messages | |
1060 // to the browser process. | |
1061 main_message_loop_.reset(); | |
1062 | |
1063 lazy_tls.Pointer()->Set(nullptr); | |
1064 | |
1065 base::MemoryCoordinatorClientRegistry::GetInstance()->Unregister(this); | |
1066 } | 966 } |
1067 | 967 |
1068 bool RenderThreadImpl::Send(IPC::Message* msg) { | 968 bool RenderThreadImpl::Send(IPC::Message* msg) { |
1069 // There are cases where we want to pump asynchronous messages while waiting | 969 // There are cases where we want to pump asynchronous messages while waiting |
1070 // synchronously for the replies to the message to be sent here. However, this | 970 // synchronously for the replies to the message to be sent here. However, this |
1071 // may create an opportunity for re-entrancy into WebKit and other subsystems, | 971 // may create an opportunity for re-entrancy into WebKit and other subsystems, |
1072 // so we need to take care to disable callbacks, timers, and pending network | 972 // so we need to take care to disable callbacks, timers, and pending network |
1073 // loads that could trigger such callbacks. | 973 // loads that could trigger such callbacks. |
1074 bool pumping_events = false; | 974 bool pumping_events = false; |
1075 if (msg->is_sync()) { | 975 if (msg->is_sync()) { |
(...skipping 1425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2501 } | 2401 } |
2502 } | 2402 } |
2503 | 2403 |
2504 void RenderThreadImpl::OnRendererInterfaceRequest( | 2404 void RenderThreadImpl::OnRendererInterfaceRequest( |
2505 mojom::RendererAssociatedRequest request) { | 2405 mojom::RendererAssociatedRequest request) { |
2506 DCHECK(!renderer_binding_.is_bound()); | 2406 DCHECK(!renderer_binding_.is_bound()); |
2507 renderer_binding_.Bind(std::move(request)); | 2407 renderer_binding_.Bind(std::move(request)); |
2508 } | 2408 } |
2509 | 2409 |
2510 } // namespace content | 2410 } // namespace content |
OLD | NEW |