ipc/chromium/src/chrome/common/process_watcher_win.cc

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
michael@0 2 // Use of this source code is governed by a BSD-style license that can be
michael@0 3 // found in the LICENSE file.
michael@0 4
michael@0 5 #include "chrome/common/process_watcher.h"
michael@0 6
michael@0 7 #include "base/message_loop.h"
michael@0 8 #include "base/object_watcher.h"
michael@0 9 #include "base/sys_info.h"
michael@0 10 #include "chrome/common/env_vars.h"
michael@0 11 #include "chrome/common/result_codes.h"
michael@0 12
michael@0 13 // Maximum amount of time (in milliseconds) to wait for the process to exit.
michael@0 14 static const int kWaitInterval = 2000;
michael@0 15
michael@0 16 namespace {
michael@0 17
michael@0 18 class TimerExpiredTask : public Task, public base::ObjectWatcher::Delegate {
michael@0 19 public:
michael@0 20 explicit TimerExpiredTask(base::ProcessHandle process) : process_(process) {
michael@0 21 watcher_.StartWatching(process_, this);
michael@0 22 }
michael@0 23
michael@0 24 virtual ~TimerExpiredTask() {
michael@0 25 if (process_) {
michael@0 26 KillProcess();
michael@0 27 DCHECK(!process_) << "Make sure to close the handle.";
michael@0 28 }
michael@0 29 }
michael@0 30
michael@0 31 // Task ---------------------------------------------------------------------
michael@0 32
michael@0 33 virtual void Run() {
michael@0 34 if (process_)
michael@0 35 KillProcess();
michael@0 36 }
michael@0 37
michael@0 38 // MessageLoop::Watcher -----------------------------------------------------
michael@0 39
michael@0 40 virtual void OnObjectSignaled(HANDLE object) {
michael@0 41 // When we're called from KillProcess, the ObjectWatcher may still be
michael@0 42 // watching. the process handle, so make sure it has stopped.
michael@0 43 watcher_.StopWatching();
michael@0 44
michael@0 45 base::CloseProcessHandle(process_);
michael@0 46 process_ = NULL;
michael@0 47 }
michael@0 48
michael@0 49 private:
michael@0 50 void KillProcess() {
michael@0 51 if (base::SysInfo::HasEnvVar(env_vars::kHeadless)) {
michael@0 52 // If running the distributed tests, give the renderer a little time
michael@0 53 // to figure out that the channel is shutdown and unwind.
michael@0 54 if (WaitForSingleObject(process_, kWaitInterval) == WAIT_OBJECT_0) {
michael@0 55 OnObjectSignaled(process_);
michael@0 56 return;
michael@0 57 }
michael@0 58 }
michael@0 59
michael@0 60 // OK, time to get frisky. We don't actually care when the process
michael@0 61 // terminates. We just care that it eventually terminates, and that's what
michael@0 62 // TerminateProcess should do for us. Don't check for the result code since
michael@0 63 // it fails quite often. This should be investigated eventually.
michael@0 64 TerminateProcess(process_, ResultCodes::HUNG);
michael@0 65
michael@0 66 // Now, just cleanup as if the process exited normally.
michael@0 67 OnObjectSignaled(process_);
michael@0 68 }
michael@0 69
michael@0 70 // The process that we are watching.
michael@0 71 base::ProcessHandle process_;
michael@0 72
michael@0 73 base::ObjectWatcher watcher_;
michael@0 74
michael@0 75 DISALLOW_EVIL_CONSTRUCTORS(TimerExpiredTask);
michael@0 76 };
michael@0 77
michael@0 78 } // namespace
michael@0 79
michael@0 80 // static
michael@0 81 void ProcessWatcher::EnsureProcessTerminated(base::ProcessHandle process
michael@0 82 , bool force
michael@0 83 ) {
michael@0 84 DCHECK(process != GetCurrentProcess());
michael@0 85
michael@0 86 if (!force) {
michael@0 87 WaitForSingleObject(process, INFINITE);
michael@0 88 base::CloseProcessHandle(process);
michael@0 89 return;
michael@0 90 }
michael@0 91
michael@0 92 // If already signaled, then we are done!
michael@0 93 if (WaitForSingleObject(process, 0) == WAIT_OBJECT_0) {
michael@0 94 base::CloseProcessHandle(process);
michael@0 95 return;
michael@0 96 }
michael@0 97
michael@0 98 MessageLoop::current()->PostDelayedTask(FROM_HERE,
michael@0 99 new TimerExpiredTask(process),
michael@0 100 kWaitInterval);
michael@0 101 }

mercurial