Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(231)

Side by Side Diff: subprocess.h

Issue 4690006: AU: Execute postinst asynchronously so that the D-Bus service is not blocked. (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/update_engine.git@master
Patch Set: address review comments Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « postinstall_runner_action_unittest.cc ('k') | subprocess.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 // A map from the asynchronous subprocess tag (see Exec) to the subprocess
97 // record structure for all active asynchronous subprocesses.
98 std::map<int, std::tr1::shared_ptr<SubprocessRecord> > subprocess_records_;
99
83 DISALLOW_COPY_AND_ASSIGN(Subprocess); 100 DISALLOW_COPY_AND_ASSIGN(Subprocess);
84 }; 101 };
85 102
86 } // namespace chromeos_update_engine 103 } // namespace chromeos_update_engine
87 104
88 #endif // CHROMEOS_PLATFORM_UPDATE_ENGINE_SUBPROCESS_H__ 105 #endif // CHROMEOS_PLATFORM_UPDATE_ENGINE_SUBPROCESS_H__
OLDNEW
« no previous file with comments | « postinstall_runner_action_unittest.cc ('k') | subprocess.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698