blob: 28b59c059cb98f8237314f4b052da6efe6778d75 [file] [log] [blame]
mukesh agrawalae30e9e2013-05-28 14:09:16 -07001// Copyright (c) 2013 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#ifndef SHILL_EXTERNAL_TASK_H_
6#define SHILL_EXTERNAL_TASK_H_
7
8#include <sys/types.h>
9
10#include <map>
11#include <string>
12#include <vector>
13
14#include <base/callback.h>
15#include <base/file_path.h>
16#include <base/memory/scoped_ptr.h>
17#include <base/memory/weak_ptr.h>
18#include <gtest/gtest_prod.h> // for FRIEND_TEST
19
20#include "shill/glib.h"
21#include "shill/rpc_task.h"
22
23namespace shill {
24
25class ControlInterface;
26class Error;
mukesh agrawal9da07772013-05-15 14:15:17 -070027class EventDispatcher;
mukesh agrawalae30e9e2013-05-28 14:09:16 -070028class ProcessKiller;
29
30class ExternalTask : public RPCTaskDelegate {
31 public:
32 ExternalTask(ControlInterface *control,
33 GLib *glib,
34 const base::WeakPtr<RPCTaskDelegate> &task_delegate,
35 const base::Callback<void(pid_t, int)> &death_callback);
mukesh agrawal9da07772013-05-15 14:15:17 -070036 virtual ~ExternalTask(); // But consider DestroyLater...
37
38 // Schedule later deletion of the ExternalTask. Useful when in the
39 // middle of an ExternalTask callback. Note that the caller _must_
40 // release ownership of |this|. For example:
41 //
42 // class Foo : public SupportsWeakPtr<Foo>, public RPCTaskDelegate {
43 // public:
44 // Foo() {
45 // task_.reset(new ExternalTask(...));
46 // }
47 //
48 // void Notify(...) {
49 // task_.release()->DestroyLater(...); // Passes ownership.
50 // }
51 //
52 // private:
53 // scoped_ptr<ExternalTask> task_;
54 // }
55 void DestroyLater(EventDispatcher *dispatcher);
mukesh agrawalae30e9e2013-05-28 14:09:16 -070056
57 // Forks off a process to run |program|, with the command-line
58 // arguments |arguments|, and the environment variables specified in
59 // |environment|.
60 //
61 // On success, returns true, and leaves |error| unmodified.
62 // On failure, returns false, and sets |error|.
63 //
64 // |environment| SHOULD NOT contain kRPCTaskServiceVariable or
65 // kRPCTaskPathVariable, as that may prevent the child process
66 // from communicating back to the ExternalTask.
67 virtual bool Start(const base::FilePath &program,
68 const std::vector<std::string> &arguments,
69 const std::map<std::string, std::string> &environment,
70 Error *error);
71 virtual void Stop();
72
73 private:
74 friend class ExternalTaskTest;
75 FRIEND_TEST(ExternalTaskTest, Destructor);
76 FRIEND_TEST(ExternalTaskTest, GetLogin);
77 FRIEND_TEST(ExternalTaskTest, Notify);
78 FRIEND_TEST(ExternalTaskTest, OnTaskDied);
79 FRIEND_TEST(ExternalTaskTest, Start);
80 FRIEND_TEST(ExternalTaskTest, Stop);
81 FRIEND_TEST(ExternalTaskTest, StopNotStarted);
82
83 // Implements RPCTaskDelegate.
84 virtual void GetLogin(std::string *user, std::string *password) override;
85 virtual void Notify(
86 const std::string &event,
87 const std::map<std::string, std::string> &details) override;
88 // Called when the external process exits.
89 static void OnTaskDied(GPid pid, gint status, gpointer data);
90
mukesh agrawal9da07772013-05-15 14:15:17 -070091 static void Destroy(ExternalTask *task);
92
mukesh agrawalae30e9e2013-05-28 14:09:16 -070093 ControlInterface *control_;
94 GLib *glib_;
95 ProcessKiller *process_killer_; // Field permits mocking.
96
97 scoped_ptr<RPCTask> rpc_task_;
98 base::WeakPtr<RPCTaskDelegate> task_delegate_;
99 base::Callback<void(pid_t, int)> death_callback_;
100
101 // The PID of the spawned process. May be 0 if no process has been
102 // spawned yet or the process has died.
103 pid_t pid_;
104
105 // Child exit watch callback source tag.
106 unsigned int child_watch_tag_;
107
108 DISALLOW_COPY_AND_ASSIGN(ExternalTask);
109};
110
111} // namespace shill
112
113#endif // SHILL_EXTERNAL_TASK_H_