blob: 7496c15eb070eaf07728976df4ab69c9a0622711 [file] [log] [blame]
Darin Petkov5a850472012-06-06 15:44:24 +02001// Copyright (c) 2012 The Chromium OS 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.
4
5#include "shill/process_killer.h"
6
7using base::Closure;
8using std::map;
9
10namespace shill {
11
12namespace {
13
14base::LazyInstance<ProcessKiller> g_process_killer = LAZY_INSTANCE_INITIALIZER;
15
16} // namespace
17
18ProcessKiller::ProcessKiller() {}
19
20ProcessKiller::~ProcessKiller() {
21 // There's no need to release any GLib child watch sources because this class
22 // is a singleton and will be destroyed when this process exits, i.e., when
23 // GLib is shut down.
24}
25
26// static
27ProcessKiller *ProcessKiller::GetInstance() {
28 return g_process_killer.Pointer();
29}
30
Darin Petkov38066762012-12-17 15:35:45 +010031void ProcessKiller::Wait(int pid, const Closure &callback) {
32 LOG(INFO) << "Waiting for pid " << pid;
Darin Petkov5a850472012-06-06 15:44:24 +020033 if (!callback.is_null()) {
34 callbacks_[pid] = callback;
35 }
36 g_child_watch_add(pid, OnProcessDied, this);
Darin Petkov38066762012-12-17 15:35:45 +010037}
38
39void ProcessKiller::Kill(int pid, const Closure &callback) {
40 Wait(pid, callback);
41 LOG(INFO) << "Killing pid " << pid;
Darin Petkov5a850472012-06-06 15:44:24 +020042 // TODO(petkov): Consider sending subsequent periodic signals and raising the
43 // signal to SIGKILL if the process keeps running.
44 kill(pid, SIGTERM);
45}
46
47// static
48void ProcessKiller::OnProcessDied(GPid pid, gint status, gpointer data) {
49 LOG(INFO) << "pid " << pid << " died, status " << status;
50 ProcessKiller *me = reinterpret_cast<ProcessKiller *>(data);
51 map<int, Closure>::iterator callback_it = me->callbacks_.find(pid);
52 if (callback_it == me->callbacks_.end()) {
53 return;
54 }
55 const Closure &callback = callback_it->second;
56 if (!callback.is_null()) {
57 LOG(INFO) << "Running callback for dead pid " << pid;
58 callback.Run();
59 }
60 me->callbacks_.erase(callback_it);
61}
62
63} // namespace shill