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

Side by Side Diff: runtime/bin/process.h

Issue 21816002: Add Process.runSync for running processe synchronously. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Combined the code from https://codereview.chromium.org/22827002/ into this change Created 7 years, 4 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
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #ifndef BIN_PROCESS_H_ 5 #ifndef BIN_PROCESS_H_
6 #define BIN_PROCESS_H_ 6 #define BIN_PROCESS_H_
7 7
8 #include "bin/builtin.h" 8 #include "bin/builtin.h"
9 #include "bin/io_buffer.h"
9 #include "bin/thread.h" 10 #include "bin/thread.h"
10 #include "platform/globals.h" 11 #include "platform/globals.h"
12 #include "platform/utils.h"
11 13
12 14
13 namespace dart { 15 namespace dart {
14 namespace bin { 16 namespace bin {
15 17
18 class ProcessResult {
19 public:
20 ProcessResult() : exit_code_(0) {}
21
22 void set_stdout_data(Dart_Handle stdout_data) {
23 stdout_data_ = stdout_data;
24 }
25 void set_stderr_data(Dart_Handle stderr_data) {
26 stderr_data_ = stderr_data;
27 }
28
29 void set_exit_code(intptr_t exit_code) { exit_code_ = exit_code; }
30
31 Dart_Handle stdout_data() { return stdout_data_; }
32 Dart_Handle stderr_data() { return stderr_data_; }
33 intptr_t exit_code() { return exit_code_; }
34
35 private:
36 Dart_Handle stdout_data_;
37 Dart_Handle stderr_data_;
38 intptr_t exit_code_;
39
40 DISALLOW_ALLOCATION();
41 };
42
43
16 class Process { 44 class Process {
17 public: 45 public:
18 // Start a new process providing access to stdin, stdout, stderr and 46 // Start a new process providing access to stdin, stdout, stderr and
19 // process exit streams. 47 // process exit streams.
20 static int Start(const char* path, 48 static int Start(const char* path,
21 char* arguments[], 49 char* arguments[],
22 intptr_t arguments_length, 50 intptr_t arguments_length,
23 const char* working_directory, 51 const char* working_directory,
24 char* environment[], 52 char* environment[],
25 intptr_t environment_length, 53 intptr_t environment_length,
26 intptr_t* in, 54 intptr_t* in,
27 intptr_t* out, 55 intptr_t* out,
28 intptr_t* err, 56 intptr_t* err,
29 intptr_t* id, 57 intptr_t* id,
30 intptr_t* exit_handler, 58 intptr_t* exit_handler,
31 char** os_error_message); 59 char** os_error_message);
32 60
61 static bool Wait(intptr_t id,
62 intptr_t in,
63 intptr_t out,
64 intptr_t err,
65 intptr_t exit_handler,
66 ProcessResult* result);
67
33 // Kill a process with a given pid. 68 // Kill a process with a given pid.
34 static bool Kill(intptr_t id, int signal); 69 static bool Kill(intptr_t id, int signal);
35 70
36 // Terminate the exit code handler thread. Does not return before 71 // Terminate the exit code handler thread. Does not return before
37 // the thread has terminated. 72 // the thread has terminated.
38 static void TerminateExitCodeHandler(); 73 static void TerminateExitCodeHandler();
39 74
40 static int GlobalExitCode() { 75 static int GlobalExitCode() {
41 MutexLocker ml(global_exit_code_mutex_); 76 MutexLocker ml(global_exit_code_mutex_);
42 return global_exit_code_; 77 return global_exit_code_;
(...skipping 12 matching lines...) Expand all
55 intptr_t pid); 90 intptr_t pid);
56 91
57 private: 92 private:
58 static int global_exit_code_; 93 static int global_exit_code_;
59 static dart::Mutex* global_exit_code_mutex_; 94 static dart::Mutex* global_exit_code_mutex_;
60 95
61 DISALLOW_ALLOCATION(); 96 DISALLOW_ALLOCATION();
62 DISALLOW_IMPLICIT_CONSTRUCTORS(Process); 97 DISALLOW_IMPLICIT_CONSTRUCTORS(Process);
63 }; 98 };
64 99
100
101 // Utility class for collecting the output when running a process
102 // synchronously by using Process::Wait. This class is sub-classed in
103 // the platform specific files to implement reading into the buffers
104 // allocated.
105 class BufferListBase {
106 protected:
107 static const intptr_t kBufferSize = 16 * 1024;
108
109 class BufferListNode {
110 public:
111 explicit BufferListNode(intptr_t size) {
112 data_ = new uint8_t[size];
113 if (data_ == NULL) FATAL("Allocation failed");
114 next_ = NULL;
115 }
116
117 ~BufferListNode() {
118 delete[] data_;
119 }
120
121 uint8_t* data_;
122 BufferListNode* next_;
123
124 private:
125 DISALLOW_IMPLICIT_CONSTRUCTORS(BufferListNode);
126 };
127
128 public:
129 BufferListBase() : head_(NULL), tail_(NULL), data_size_(0), free_size_(0) {}
130 ~BufferListBase() {
131 ASSERT(head_ == NULL);
132 ASSERT(tail_ == NULL);
133 }
134
135 // Returns the collected data as a Uint8List. If an error occours an
136 // error handle is returned.
137 Dart_Handle GetData() {
138 uint8_t* buffer;
139 intptr_t buffer_position = 0;
140 Dart_Handle result = IOBuffer::Allocate(data_size_, &buffer);
141 if (Dart_IsError(result)) {
142 Free();
143 return result;
144 }
145 for (BufferListNode* current = head_;
146 current != NULL;
147 current = current->next_) {
148 intptr_t to_copy = dart::Utils::Minimum(data_size_, kBufferSize);
149 memmove(buffer + buffer_position, current->data_, to_copy);
150 buffer_position += to_copy;
151 data_size_ -= to_copy;
152 }
153 ASSERT(data_size_ == 0);
154 Free();
155 return result;
156 }
157
158 protected:
159 void Allocate() {
160 ASSERT(free_size_ == 0);
161 BufferListNode* node = new BufferListNode(kBufferSize);
162 if (head_ == NULL) {
163 head_ = node;
164 tail_ = node;
165 } else {
166 ASSERT(tail_->next_ == NULL);
167 tail_->next_ = node;
168 tail_ = node;
169 }
170 free_size_ = kBufferSize;
171 }
172
173 void Free() {
174 for (BufferListNode* current = head_;
175 current != NULL;
176 current = current->next_) {
177 }
Bill Hesse 2013/08/13 08:34:48 Something seems missing in this for loop.
Søren Gjesse 2013/08/13 13:00:43 Added delete current;
178 head_ = NULL;
179 tail_ = NULL;
180 data_size_ = 0;
181 free_size_ = 0;
182 }
183
184 // Linked list for data collected.
185 BufferListNode* head_;
186 BufferListNode* tail_;
187
188 // Number of bytes of data collected in the linked list.
189 intptr_t data_size_;
190
191 // Number of free bytes in the last node in the list.
192 intptr_t free_size_;
193 };
194
65 } // namespace bin 195 } // namespace bin
66 } // namespace dart 196 } // namespace dart
67 197
68 #endif // BIN_PROCESS_H_ 198 #endif // BIN_PROCESS_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698