Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(225)

Side by Side Diff: content/common/child_thread.cc

Issue 10834068: On Posix, make all child processes quit when the browser dies, not just the renderers. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/common/child_thread.h" 5 #include "content/common/child_thread.h"
6 6
7 #include "base/allocator/allocator_extension.h" 7 #include "base/allocator/allocator_extension.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/message_loop.h" 9 #include "base/message_loop.h"
10 #include "base/process.h" 10 #include "base/process.h"
(...skipping 14 matching lines...) Expand all
25 #include "ipc/ipc_sync_message_filter.h" 25 #include "ipc/ipc_sync_message_filter.h"
26 #include "webkit/glue/webkit_glue.h" 26 #include "webkit/glue/webkit_glue.h"
27 27
28 #if defined(OS_WIN) 28 #if defined(OS_WIN)
29 #include "content/common/handle_enumerator_win.h" 29 #include "content/common/handle_enumerator_win.h"
30 #endif 30 #endif
31 31
32 using content::ResourceDispatcher; 32 using content::ResourceDispatcher;
33 using tracked_objects::ThreadData; 33 using tracked_objects::ThreadData;
34 34
35 namespace {
36
37 #if defined(OS_POSIX)
38
39 class SuicideOnChannelErrorFilter : public IPC::ChannelProxy::MessageFilter {
40 public:
41 // IPC::ChannelProxy::MessageFilter
42 virtual void OnChannelError() OVERRIDE {
43 // For renderer/worker processes:
44 // On POSIX, at least, one can install an unload handler which loops
45 // forever and leave behind a renderer process which eats 100% CPU forever.
46 //
47 // This is because the terminate signals (ViewMsg_ShouldClose and the error
48 // from the IPC channel) are routed to the main message loop but never
49 // processed (because that message loop is stuck in V8).
50 //
51 // One could make the browser SIGKILL the renderers, but that leaves open a
52 // large window where a browser failure (or a user, manually terminating
53 // the browser because "it's stuck") will leave behind a process eating all
54 // the CPU.
55 //
56 // So, we install a filter on the channel so that we can process this event
57 // here and kill the process.
58 //
59 // We want to kill this process after giving it 30 seconds to run the exit
60 // handlers. SIGALRM has a default disposition of terminating the
61 // application.
62 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kChildCleanExit))
63 alarm(30);
64 else
65 _exit(0);
66 }
67
68 protected:
69 virtual ~SuicideOnChannelErrorFilter() {}
70 };
71
72 #endif // OS(POSIX)
73
74 } // namespace
75
35 ChildThread::ChildThread() { 76 ChildThread::ChildThread() {
36 channel_name_ = CommandLine::ForCurrentProcess()->GetSwitchValueASCII( 77 channel_name_ = CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
37 switches::kProcessChannelID); 78 switches::kProcessChannelID);
38 Init(); 79 Init();
39 } 80 }
40 81
41 ChildThread::ChildThread(const std::string& channel_name) 82 ChildThread::ChildThread(const std::string& channel_name)
42 : channel_name_(channel_name) { 83 : channel_name_(channel_name) {
43 Init(); 84 Init();
44 } 85 }
(...skipping 14 matching lines...) Expand all
59 file_system_dispatcher_.reset(new FileSystemDispatcher()); 100 file_system_dispatcher_.reset(new FileSystemDispatcher());
60 quota_dispatcher_.reset(new QuotaDispatcher()); 101 quota_dispatcher_.reset(new QuotaDispatcher());
61 102
62 sync_message_filter_ = 103 sync_message_filter_ =
63 new IPC::SyncMessageFilter(ChildProcess::current()->GetShutDownEvent()); 104 new IPC::SyncMessageFilter(ChildProcess::current()->GetShutDownEvent());
64 histogram_message_filter_ = new content::ChildHistogramMessageFilter(); 105 histogram_message_filter_ = new content::ChildHistogramMessageFilter();
65 106
66 channel_->AddFilter(histogram_message_filter_.get()); 107 channel_->AddFilter(histogram_message_filter_.get());
67 channel_->AddFilter(sync_message_filter_.get()); 108 channel_->AddFilter(sync_message_filter_.get());
68 channel_->AddFilter(new ChildTraceMessageFilter()); 109 channel_->AddFilter(new ChildTraceMessageFilter());
110
111 #if defined(OS_POSIX)
112 // Check that --process-type is specified so we don't do this in unit tests
113 // and single-process mode.
114 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessType))
115 channel_->AddFilter(new SuicideOnChannelErrorFilter());
116 #endif
69 } 117 }
70 118
71 ChildThread::~ChildThread() { 119 ChildThread::~ChildThread() {
72 #ifdef IPC_MESSAGE_LOG_ENABLED 120 #ifdef IPC_MESSAGE_LOG_ENABLED
73 IPC::Logging::GetInstance()->SetIPCSender(NULL); 121 IPC::Logging::GetInstance()->SetIPCSender(NULL);
74 #endif 122 #endif
75 123
76 channel_->RemoveFilter(histogram_message_filter_.get()); 124 channel_->RemoveFilter(histogram_message_filter_.get());
77 channel_->RemoveFilter(sync_message_filter_.get()); 125 channel_->RemoveFilter(sync_message_filter_.get());
78 126
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 } 325 }
278 326
279 // The child process shutdown sequence is a request response based mechanism, 327 // The child process shutdown sequence is a request response based mechanism,
280 // where we send out an initial feeler request to the child process host 328 // where we send out an initial feeler request to the child process host
281 // instance in the browser to verify if it's ok to shutdown the child process. 329 // instance in the browser to verify if it's ok to shutdown the child process.
282 // The browser then sends back a response if it's ok to shutdown. This avoids 330 // The browser then sends back a response if it's ok to shutdown. This avoids
283 // race conditions if the process refcount is 0 but there's an IPC message 331 // race conditions if the process refcount is 0 but there's an IPC message
284 // inflight that would addref it. 332 // inflight that would addref it.
285 Send(new ChildProcessHostMsg_ShutdownRequest); 333 Send(new ChildProcessHostMsg_ShutdownRequest);
286 } 334 }
OLDNEW
« no previous file with comments | « content/browser/renderer_host/render_process_host_impl.cc ('k') | content/public/common/content_switches.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698