blob: 2880dd7f58c734ac5cba3f074248bd76def5c22c [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>
Ben Chancd477322014-10-17 14:19:30 -070011#include <memory>
mukesh agrawalae30e9e2013-05-28 14:09:16 -070012#include <string>
13#include <vector>
14
15#include <base/callback.h>
Ben Chana0ddf462014-02-06 11:32:42 -080016#include <base/files/file_path.h>
mukesh agrawalae30e9e2013-05-28 14:09:16 -070017#include <base/memory/weak_ptr.h>
18#include <gtest/gtest_prod.h> // for FRIEND_TEST
19
mukesh agrawalae30e9e2013-05-28 14:09:16 -070020#include "shill/rpc_task.h"
21
22namespace shill {
23
24class ControlInterface;
25class Error;
mukesh agrawal9da07772013-05-15 14:15:17 -070026class EventDispatcher;
Peter Qiua24480a2015-08-11 23:09:54 -070027class ProcessManager;
mukesh agrawalae30e9e2013-05-28 14:09:16 -070028
29class ExternalTask : public RPCTaskDelegate {
30 public:
Paul Stewarta794cd62015-06-16 13:13:10 -070031 ExternalTask(ControlInterface* control,
Peter Qiua24480a2015-08-11 23:09:54 -070032 ProcessManager* process_manager,
Paul Stewarta794cd62015-06-16 13:13:10 -070033 const base::WeakPtr<RPCTaskDelegate>& task_delegate,
34 const base::Callback<void(pid_t, int)>& death_callback);
Ben Chan5ea763b2014-08-13 11:07:54 -070035 ~ExternalTask() override; // But consider DestroyLater...
mukesh agrawal9da07772013-05-15 14:15:17 -070036
37 // Schedule later deletion of the ExternalTask. Useful when in the
38 // middle of an ExternalTask callback. Note that the caller _must_
39 // release ownership of |this|. For example:
40 //
41 // class Foo : public SupportsWeakPtr<Foo>, public RPCTaskDelegate {
42 // public:
43 // Foo() {
44 // task_.reset(new ExternalTask(...));
45 // }
46 //
47 // void Notify(...) {
48 // task_.release()->DestroyLater(...); // Passes ownership.
49 // }
50 //
51 // private:
Ben Chancd477322014-10-17 14:19:30 -070052 // std::unique_ptr<ExternalTask> task_;
mukesh agrawal9da07772013-05-15 14:15:17 -070053 // }
Paul Stewarta794cd62015-06-16 13:13:10 -070054 void DestroyLater(EventDispatcher* dispatcher);
mukesh agrawalae30e9e2013-05-28 14:09:16 -070055
56 // Forks off a process to run |program|, with the command-line
57 // arguments |arguments|, and the environment variables specified in
58 // |environment|.
59 //
mukesh agrawalc4f9aa02013-08-15 19:23:13 -070060 // If |terminate_with_parent| is true, the child process will be
61 // configured to terminate itself if this process dies. Otherwise,
62 // the child process will retain its default behavior.
63 //
mukesh agrawalae30e9e2013-05-28 14:09:16 -070064 // On success, returns true, and leaves |error| unmodified.
65 // On failure, returns false, and sets |error|.
66 //
67 // |environment| SHOULD NOT contain kRPCTaskServiceVariable or
68 // kRPCTaskPathVariable, as that may prevent the child process
69 // from communicating back to the ExternalTask.
Paul Stewarta794cd62015-06-16 13:13:10 -070070 virtual bool Start(const base::FilePath& program,
71 const std::vector<std::string>& arguments,
72 const std::map<std::string, std::string>& environment,
mukesh agrawalc4f9aa02013-08-15 19:23:13 -070073 bool terminate_with_parent,
Paul Stewarta794cd62015-06-16 13:13:10 -070074 Error* error);
mukesh agrawalae30e9e2013-05-28 14:09:16 -070075 virtual void Stop();
76
77 private:
78 friend class ExternalTaskTest;
79 FRIEND_TEST(ExternalTaskTest, Destructor);
80 FRIEND_TEST(ExternalTaskTest, GetLogin);
81 FRIEND_TEST(ExternalTaskTest, Notify);
82 FRIEND_TEST(ExternalTaskTest, OnTaskDied);
83 FRIEND_TEST(ExternalTaskTest, Start);
84 FRIEND_TEST(ExternalTaskTest, Stop);
85 FRIEND_TEST(ExternalTaskTest, StopNotStarted);
86
87 // Implements RPCTaskDelegate.
Paul Stewarta794cd62015-06-16 13:13:10 -070088 void GetLogin(std::string* user, std::string* password) override;
Alex Vakulenko016fa0e2014-08-11 15:59:58 -070089 void Notify(
Paul Stewarta794cd62015-06-16 13:13:10 -070090 const std::string& event,
91 const std::map<std::string, std::string>& details) override;
Peter Qiua24480a2015-08-11 23:09:54 -070092
mukesh agrawalae30e9e2013-05-28 14:09:16 -070093 // Called when the external process exits.
Peter Qiua24480a2015-08-11 23:09:54 -070094 void OnTaskDied(int exit_status);
mukesh agrawalae30e9e2013-05-28 14:09:16 -070095
Paul Stewarta794cd62015-06-16 13:13:10 -070096 static void Destroy(ExternalTask* task);
mukesh agrawal9da07772013-05-15 14:15:17 -070097
Paul Stewarta794cd62015-06-16 13:13:10 -070098 ControlInterface* control_;
Peter Qiua24480a2015-08-11 23:09:54 -070099 ProcessManager* process_manager_;
mukesh agrawalae30e9e2013-05-28 14:09:16 -0700100
Ben Chancd477322014-10-17 14:19:30 -0700101 std::unique_ptr<RPCTask> rpc_task_;
mukesh agrawalae30e9e2013-05-28 14:09:16 -0700102 base::WeakPtr<RPCTaskDelegate> task_delegate_;
103 base::Callback<void(pid_t, int)> death_callback_;
104
105 // The PID of the spawned process. May be 0 if no process has been
106 // spawned yet or the process has died.
107 pid_t pid_;
108
mukesh agrawalae30e9e2013-05-28 14:09:16 -0700109 DISALLOW_COPY_AND_ASSIGN(ExternalTask);
110};
111
112} // namespace shill
113
114#endif // SHILL_EXTERNAL_TASK_H_