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.

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

mercurial