OLD | NEW |
---|---|
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_SUBPROCESS_H__ | 5 #ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_SUBPROCESS_H__ |
6 #define CHROMEOS_PLATFORM_UPDATE_ENGINE_SUBPROCESS_H__ | 6 #define CHROMEOS_PLATFORM_UPDATE_ENGINE_SUBPROCESS_H__ |
7 | 7 |
8 #include <map> | 8 #include <map> |
9 #include <string> | 9 #include <string> |
10 #include <tr1/memory> | |
10 #include <vector> | 11 #include <vector> |
12 | |
11 #include <glib.h> | 13 #include <glib.h> |
14 | |
12 #include "base/basictypes.h" | 15 #include "base/basictypes.h" |
13 #include "base/logging.h" | 16 #include "base/logging.h" |
14 | 17 |
15 // The Subprocess class is a singleton. It's used to spawn off a subprocess | 18 // The Subprocess class is a singleton. It's used to spawn off a subprocess |
16 // and get notified when the subprocess exits. The result of Exec() can | 19 // and get notified when the subprocess exits. The result of Exec() can |
17 // be saved and used to cancel the callback request. If you know you won't | 20 // be saved and used to cancel the callback request. If you know you won't |
18 // call CancelExec(), you may safely lose the return value from Exec(). | 21 // call CancelExec(), you may safely lose the return value from Exec(). |
19 | 22 |
20 namespace chromeos_update_engine { | 23 namespace chromeos_update_engine { |
21 | 24 |
22 class Subprocess { | 25 class Subprocess { |
23 public: | 26 public: |
27 typedef void(*ExecCallback)(int return_code, | |
28 const std::string& output, | |
29 void *p); | |
30 | |
24 static void Init() { | 31 static void Init() { |
25 CHECK(!subprocess_singleton_); | 32 CHECK(!subprocess_singleton_); |
26 subprocess_singleton_ = new Subprocess; | 33 subprocess_singleton_ = new Subprocess; |
27 } | 34 } |
28 | |
29 typedef void(*ExecCallback)(int return_code, void *p); | |
30 | 35 |
31 // Returns a tag > 0 on success. | 36 // Returns a tag > 0 on success. |
32 uint32_t Exec(const std::vector<std::string>& cmd, | 37 uint32_t Exec(const std::vector<std::string>& cmd, |
33 ExecCallback callback, | 38 ExecCallback callback, |
34 void* p); | 39 void* p); |
35 | 40 |
36 // Used to cancel the callback. The process will still run to completion. | 41 // Used to cancel the callback. The process will still run to completion. |
37 void CancelExec(uint32_t tag); | 42 void CancelExec(uint32_t tag); |
38 | 43 |
39 // Executes a command synchronously. Returns true on success. | 44 // Executes a command synchronously. Returns true on success. |
40 static bool SynchronousExecFlags(const std::vector<std::string>& cmd, | 45 static bool SynchronousExecFlags(const std::vector<std::string>& cmd, |
41 int* return_code, | 46 int* return_code, |
42 GSpawnFlags flags); | 47 GSpawnFlags flags); |
43 static bool SynchronousExec(const std::vector<std::string>& cmd, | 48 static bool SynchronousExec(const std::vector<std::string>& cmd, |
44 int* return_code) { | 49 int* return_code) { |
45 return SynchronousExecFlags(cmd, return_code, static_cast<GSpawnFlags>(0)); | 50 return SynchronousExecFlags(cmd, return_code, static_cast<GSpawnFlags>(0)); |
46 } | 51 } |
47 | 52 |
48 // Gets the one instance | 53 // Gets the one instance |
49 static Subprocess& Get() { | 54 static Subprocess& Get() { |
50 return *subprocess_singleton_; | 55 return *subprocess_singleton_; |
51 } | 56 } |
52 | 57 |
53 // Returns true iff there is at least one subprocess we're waiting on. | 58 // Returns true iff there is at least one subprocess we're waiting on. |
54 bool SubprocessInFlight() { | 59 bool SubprocessInFlight(); |
55 for (std::map<int, SubprocessCallbackRecord>::iterator it = | 60 |
56 callback_records_.begin(); | |
57 it != callback_records_.end(); ++it) { | |
58 if (it->second.callback) | |
59 return true; | |
60 } | |
61 return false; | |
62 } | |
63 private: | 61 private: |
64 // The global instance | 62 struct SubprocessRecord { |
65 static Subprocess* subprocess_singleton_; | 63 SubprocessRecord() |
64 : tag(0), | |
65 callback(NULL), | |
66 callback_data(NULL), | |
67 gioout(NULL), | |
68 gioout_tag(0) {} | |
69 uint32_t tag; | |
70 ExecCallback callback; | |
71 void* callback_data; | |
72 GIOChannel* gioout; | |
73 guint gioout_tag; | |
74 std::string stdout; | |
75 }; | |
76 | |
77 Subprocess() {} | |
66 | 78 |
67 // Callback for when any subprocess terminates. This calls the user | 79 // Callback for when any subprocess terminates. This calls the user |
68 // requested callback. | 80 // requested callback. |
69 static void GChildExitedCallback(GPid pid, gint status, gpointer data); | 81 static void GChildExitedCallback(GPid pid, gint status, gpointer data); |
70 | 82 |
71 // Callback which runs in the child before exec to redirect stderr onto | 83 // Callback which runs in the child before exec to redirect stderr onto |
72 // stdout. | 84 // stdout. |
73 static void GRedirectStderrToStdout(gpointer user_data); | 85 static void GRedirectStderrToStdout(gpointer user_data); |
74 | 86 |
75 struct SubprocessCallbackRecord { | 87 // Callback which runs whenever there is input available on the subprocess |
76 ExecCallback callback; | 88 // stdout pipe. |
77 void* callback_data; | 89 static gboolean GStdoutWatchCallback(GIOChannel* source, |
78 }; | 90 GIOCondition condition, |
91 gpointer data); | |
79 | 92 |
80 std::map<int, SubprocessCallbackRecord> callback_records_; | 93 // The global instance |
94 static Subprocess* subprocess_singleton_; | |
81 | 95 |
82 Subprocess() {} | 96 std::map<int, std::tr1::shared_ptr<SubprocessRecord> > subprocess_records_; |
adlr
2010/11/10 22:15:38
comment about what the int is?
petkov
2010/11/10 22:22:49
Done.
| |
97 | |
83 DISALLOW_COPY_AND_ASSIGN(Subprocess); | 98 DISALLOW_COPY_AND_ASSIGN(Subprocess); |
84 }; | 99 }; |
85 | 100 |
86 } // namespace chromeos_update_engine | 101 } // namespace chromeos_update_engine |
87 | 102 |
88 #endif // CHROMEOS_PLATFORM_UPDATE_ENGINE_SUBPROCESS_H__ | 103 #endif // CHROMEOS_PLATFORM_UPDATE_ENGINE_SUBPROCESS_H__ |
OLD | NEW |