Chromium Code Reviews| 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 |