blob: 4e1383e7ca57206533c347b83c55c87e86dbb002 [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
31void ProcessKiller::Kill(int pid, const Closure &callback) {
32 LOG(INFO) << "Killing pid " << pid;
33 if (!callback.is_null()) {
34 callbacks_[pid] = callback;
35 }
36 g_child_watch_add(pid, OnProcessDied, this);
37 // TODO(petkov): Consider sending subsequent periodic signals and raising the
38 // signal to SIGKILL if the process keeps running.
39 kill(pid, SIGTERM);
40}
41
42// static
43void ProcessKiller::OnProcessDied(GPid pid, gint status, gpointer data) {
44 LOG(INFO) << "pid " << pid << " died, status " << status;
45 ProcessKiller *me = reinterpret_cast<ProcessKiller *>(data);
46 map<int, Closure>::iterator callback_it = me->callbacks_.find(pid);
47 if (callback_it == me->callbacks_.end()) {
48 return;
49 }
50 const Closure &callback = callback_it->second;
51 if (!callback.is_null()) {
52 LOG(INFO) << "Running callback for dead pid " << pid;
53 callback.Run();
54 }
55 me->callbacks_.erase(callback_it);
56}
57
58} // namespace shill