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

Side by Side Diff: chromeos/process_proxy/process_proxy.cc

Issue 12433023: Move chrome/browser/chromeos/process_proxy to chromeos (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 7 years, 9 months 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 | « chromeos/process_proxy/process_proxy.h ('k') | chromeos/process_proxy/process_proxy_registry.h » ('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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium 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 #include "chrome/browser/chromeos/process_proxy/process_proxy.h" 5 #include "chromeos/process_proxy/process_proxy.h"
6 6
7 #include <fcntl.h> 7 #include <fcntl.h>
8 #include <stdlib.h> 8 #include <stdlib.h>
9 #include <sys/ioctl.h> 9 #include <sys/ioctl.h>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/command_line.h" 12 #include "base/command_line.h"
13 #include "base/file_util.h" 13 #include "base/file_util.h"
14 #include "base/posix/eintr_wrapper.h" 14 #include "base/posix/eintr_wrapper.h"
15 #include "base/process_util.h" 15 #include "base/process_util.h"
16 #include "base/logging.h" 16 #include "base/logging.h"
17 #include "base/threading/thread.h" 17 #include "base/threading/thread.h"
18 #include "chrome/browser/chromeos/process_proxy/process_output_watcher.h" 18 #include "chromeos/process_proxy/process_output_watcher.h"
19 #include "content/public/browser/browser_thread.h"
20 19
21 namespace { 20 namespace {
22 21
23 enum PipeEnd { 22 enum PipeEnd {
24 PIPE_END_READ, 23 PIPE_END_READ,
25 PIPE_END_WRITE 24 PIPE_END_WRITE
26 }; 25 };
27 26
28 enum PseudoTerminalFd { 27 enum PseudoTerminalFd {
29 PT_MASTER_FD, 28 PT_MASTER_FD,
30 PT_SLAVE_FD 29 PT_SLAVE_FD
31 }; 30 };
32 31
33 const int kInvalidFd = -1; 32 const int kInvalidFd = -1;
34 33
35 } // namespace 34 } // namespace
36 35
36 namespace chromeos {
37
37 ProcessProxy::ProcessProxy(): process_launched_(false), 38 ProcessProxy::ProcessProxy(): process_launched_(false),
38 callback_set_(false), 39 callback_set_(false),
39 watcher_started_(false) { 40 watcher_started_(false) {
40 // Set pipes to initial, invalid value so we can easily know if a pipe was 41 // Set pipes to initial, invalid value so we can easily know if a pipe was
41 // opened by us. 42 // opened by us.
42 ClearAllFdPairs(); 43 ClearAllFdPairs();
43 }; 44 };
44 45
45 bool ProcessProxy::Open(const std::string& command, pid_t* pid) { 46 bool ProcessProxy::Open(const std::string& command, pid_t* pid) {
46 if (process_launched_) 47 if (process_launched_)
47 return false; 48 return false;
48 49
49 if (!CreatePseudoTerminalPair(pt_pair_)) { 50 if (!CreatePseudoTerminalPair(pt_pair_)) {
50 return false; 51 return false;
51 } 52 }
52 53
53 process_launched_ = LaunchProcess(command, pt_pair_[PT_SLAVE_FD], &pid_); 54 process_launched_ = LaunchProcess(command, pt_pair_[PT_SLAVE_FD], &pid_);
54 55
55 if (process_launched_) { 56 if (process_launched_) {
56 // We won't need these anymore. These will be used by the launched process. 57 // We won't need these anymore. These will be used by the launched process.
57 CloseFd(&pt_pair_[PT_SLAVE_FD]); 58 CloseFd(&pt_pair_[PT_SLAVE_FD]);
58 *pid = pid_; 59 *pid = pid_;
59 LOG(WARNING) << "Process launched: " << pid_; 60 LOG(WARNING) << "Process launched: " << pid_;
60 } else { 61 } else {
61 CloseFdPair(pt_pair_); 62 CloseFdPair(pt_pair_);
62 } 63 }
63 return process_launched_; 64 return process_launched_;
64 } 65 }
65 66
66 bool ProcessProxy::StartWatchingOnThread(base::Thread* watch_thread, 67 bool ProcessProxy::StartWatchingOnThread(
67 const ProcessOutputCallback& callback) { 68 base::Thread* watch_thread,
69 const ProcessOutputCallback& callback) {
68 DCHECK(process_launched_); 70 DCHECK(process_launched_);
69 if (watcher_started_) 71 if (watcher_started_)
70 return false; 72 return false;
71 if (pipe(shutdown_pipe_)) 73 if (pipe(shutdown_pipe_))
72 return false; 74 return false;
73 75
74 // We give ProcessOutputWatcher a copy of master to make life easier during 76 // We give ProcessOutputWatcher a copy of master to make life easier during
75 // tear down. 77 // tear down.
76 // TODO(tbarzic): improve fd managment. 78 // TODO(tbarzic): improve fd managment.
77 int master_copy = HANDLE_EINTR(dup(pt_pair_[PT_MASTER_FD])); 79 int master_copy = HANDLE_EINTR(dup(pt_pair_[PT_MASTER_FD]));
78 if (master_copy == -1) 80 if (master_copy == -1)
79 return false; 81 return false;
80 82
81 callback_set_ = true; 83 callback_set_ = true;
82 callback_ = callback; 84 callback_ = callback;
85 callback_runner_ = base::MessageLoopProxy::current();
83 86
84 // This object will delete itself once watching is stopped. 87 // This object will delete itself once watching is stopped.
85 // It also takes ownership of the passed fds. 88 // It also takes ownership of the passed fds.
86 ProcessOutputWatcher* output_watcher = 89 ProcessOutputWatcher* output_watcher =
87 new ProcessOutputWatcher(master_copy, 90 new ProcessOutputWatcher(master_copy,
88 shutdown_pipe_[PIPE_END_READ], 91 shutdown_pipe_[PIPE_END_READ],
89 base::Bind(&ProcessProxy::OnProcessOutput, 92 base::Bind(&ProcessProxy::OnProcessOutput,
90 this)); 93 this));
91 94
92 // Output watcher took ownership of the read end of shutdown pipe. 95 // Output watcher took ownership of the read end of shutdown pipe.
93 shutdown_pipe_[PIPE_END_READ] = -1; 96 shutdown_pipe_[PIPE_END_READ] = -1;
94 97
95 // |watch| thread is blocked by |output_watcher| from now on. 98 // |watch| thread is blocked by |output_watcher| from now on.
96 watch_thread->message_loop()->PostTask(FROM_HERE, 99 watch_thread->message_loop()->PostTask(FROM_HERE,
97 base::Bind(&ProcessOutputWatcher::Start, 100 base::Bind(&ProcessOutputWatcher::Start,
98 base::Unretained(output_watcher))); 101 base::Unretained(output_watcher)));
99 watcher_started_ = true; 102 watcher_started_ = true;
100 return true; 103 return true;
101 } 104 }
102 105
103 void ProcessProxy::OnProcessOutput(ProcessOutputType type, 106 void ProcessProxy::OnProcessOutput(ProcessOutputType type,
104 const std::string& output) { 107 const std::string& output) {
105 // We have to check if callback is set on FILE thread.. 108 if (!callback_runner_)
106 if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)) {
107 content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE,
108 base::Bind(&ProcessProxy::OnProcessOutput, this, type, output));
109 return; 109 return;
110 }
111 110
111 callback_runner_->PostTask(
112 FROM_HERE,
113 base::Bind(&ProcessProxy::CallOnProcessOutputCallback,
114 this, type, output));
115 }
116
117 void ProcessProxy::CallOnProcessOutputCallback(ProcessOutputType type,
118 const std::string& output) {
112 // We may receive some output even after Close was called (crosh process does 119 // We may receive some output even after Close was called (crosh process does
113 // not have to quit instantly, or there may be some trailing data left in 120 // not have to quit instantly, or there may be some trailing data left in
114 // output stream fds). In that case owner of the callback may be gone so we 121 // output stream fds). In that case owner of the callback may be gone so we
115 // don't want to send it anything. |callback_set_| is reset when this gets 122 // don't want to send it anything. |callback_set_| is reset when this gets
116 // closed. 123 // closed.
117 if (callback_set_) 124 if (callback_set_)
118 callback_.Run(type, output); 125 callback_.Run(type, output);
119 } 126 }
120 127
121 bool ProcessProxy::StopWatching() { 128 bool ProcessProxy::StopWatching() {
122 if (!watcher_started_) 129 if (!watcher_started_)
123 return true; 130 return true;
124 // Signal Watcher that we are done. We use self-pipe trick to unblock watcher. 131 // Signal Watcher that we are done. We use self-pipe trick to unblock watcher.
125 // Anything may be written to the pipe. 132 // Anything may be written to the pipe.
126 const char message[] = "q"; 133 const char message[] = "q";
127 return file_util::WriteFileDescriptor(shutdown_pipe_[PIPE_END_WRITE], 134 return file_util::WriteFileDescriptor(shutdown_pipe_[PIPE_END_WRITE],
128 message, sizeof(message)); 135 message, sizeof(message));
129 } 136 }
130 137
131 void ProcessProxy::Close() { 138 void ProcessProxy::Close() {
132 if (!process_launched_) 139 if (!process_launched_)
133 return; 140 return;
134 141
135 process_launched_ = false; 142 process_launched_ = false;
136 callback_set_ = false; 143 callback_set_ = false;
144 callback_ = ProcessOutputCallback();
145 callback_runner_ = NULL;
137 146
138 base::KillProcess(pid_, 0, true /* wait */); 147 base::KillProcess(pid_, 0, true /* wait */);
139 148
140 // TODO(tbarzic): What if this fails? 149 // TODO(tbarzic): What if this fails?
141 StopWatching(); 150 StopWatching();
142 151
143 CloseAllFdPairs(); 152 CloseAllFdPairs();
144 } 153 }
145 154
146 bool ProcessProxy::Write(const std::string& text) { 155 bool ProcessProxy::Write(const std::string& text) {
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 254
246 void ProcessProxy::ClearAllFdPairs() { 255 void ProcessProxy::ClearAllFdPairs() {
247 ClearFdPair(pt_pair_); 256 ClearFdPair(pt_pair_);
248 ClearFdPair(shutdown_pipe_); 257 ClearFdPair(shutdown_pipe_);
249 } 258 }
250 259
251 void ProcessProxy::ClearFdPair(int* pipe) { 260 void ProcessProxy::ClearFdPair(int* pipe) {
252 pipe[PIPE_END_READ] = kInvalidFd; 261 pipe[PIPE_END_READ] = kInvalidFd;
253 pipe[PIPE_END_WRITE] = kInvalidFd; 262 pipe[PIPE_END_WRITE] = kInvalidFd;
254 } 263 }
264
265 } // namespace chromeos
OLDNEW
« no previous file with comments | « chromeos/process_proxy/process_proxy.h ('k') | chromeos/process_proxy/process_proxy_registry.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698