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

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

Issue 2596543002: Fix Process.runSync error handling. (Closed)
Patch Set: Address comments Created 3 years, 12 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
« no previous file with comments | « no previous file | runtime/bin/process_android.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) 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 RUNTIME_BIN_PROCESS_H_ 5 #ifndef RUNTIME_BIN_PROCESS_H_
6 #define RUNTIME_BIN_PROCESS_H_ 6 #define RUNTIME_BIN_PROCESS_H_
7 7
8 #include <errno.h>
9
8 #include "bin/builtin.h" 10 #include "bin/builtin.h"
9 #include "bin/io_buffer.h" 11 #include "bin/io_buffer.h"
10 #include "bin/lockers.h" 12 #include "bin/lockers.h"
11 #include "bin/thread.h" 13 #include "bin/thread.h"
12 #include "platform/globals.h" 14 #include "platform/globals.h"
15 #if !defined(TARGET_OS_WINDOWS)
16 #include "platform/signal_blocker.h"
17 #endif
13 #include "platform/utils.h" 18 #include "platform/utils.h"
14 19
15 namespace dart { 20 namespace dart {
16 namespace bin { 21 namespace bin {
17 22
18 class ProcessResult { 23 class ProcessResult {
19 public: 24 public:
20 ProcessResult() : exit_code_(0) {} 25 ProcessResult() : exit_code_(0) {}
21 26
22 void set_stdout_data(Dart_Handle stdout_data) { stdout_data_ = stdout_data; } 27 void set_stdout_data(Dart_Handle stdout_data) { stdout_data_ = stdout_data; }
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 // the platform specific files to implement reading into the buffers 201 // the platform specific files to implement reading into the buffers
197 // allocated. 202 // allocated.
198 class BufferListBase { 203 class BufferListBase {
199 protected: 204 protected:
200 static const intptr_t kBufferSize = 16 * 1024; 205 static const intptr_t kBufferSize = 16 * 1024;
201 206
202 class BufferListNode { 207 class BufferListNode {
203 public: 208 public:
204 explicit BufferListNode(intptr_t size) { 209 explicit BufferListNode(intptr_t size) {
205 data_ = new uint8_t[size]; 210 data_ = new uint8_t[size];
206 if (data_ == NULL) FATAL("Allocation failed"); 211 // We check for a failed allocation below in Allocate()
207 next_ = NULL; 212 next_ = NULL;
208 } 213 }
209 214
210 ~BufferListNode() { delete[] data_; } 215 ~BufferListNode() { delete[] data_; }
211 216
217 bool Valid() const { return data_ != NULL; }
218
219 uint8_t* data() const { return data_; }
220 BufferListNode* next() const { return next_; }
221 void set_next(BufferListNode* n) { next_ = n; }
222
223 private:
212 uint8_t* data_; 224 uint8_t* data_;
213 BufferListNode* next_; 225 BufferListNode* next_;
214 226
215 private:
216 DISALLOW_IMPLICIT_CONSTRUCTORS(BufferListNode); 227 DISALLOW_IMPLICIT_CONSTRUCTORS(BufferListNode);
217 }; 228 };
218 229
219 public: 230 public:
220 BufferListBase() : head_(NULL), tail_(NULL), data_size_(0), free_size_(0) {} 231 BufferListBase() : head_(NULL), tail_(NULL), data_size_(0), free_size_(0) {}
221 ~BufferListBase() { 232 ~BufferListBase() {
222 ASSERT(head_ == NULL); 233 Free();
223 ASSERT(tail_ == NULL); 234 DEBUG_ASSERT(IsEmpty());
224 } 235 }
225 236
226 // Returns the collected data as a Uint8List. If an error occours an 237 // Returns the collected data as a Uint8List. If an error occours an
227 // error handle is returned. 238 // error handle is returned.
228 Dart_Handle GetData() { 239 Dart_Handle GetData() {
229 uint8_t* buffer; 240 uint8_t* buffer;
230 intptr_t buffer_position = 0; 241 intptr_t buffer_position = 0;
231 Dart_Handle result = IOBuffer::Allocate(data_size_, &buffer); 242 Dart_Handle result = IOBuffer::Allocate(data_size_, &buffer);
232 if (Dart_IsError(result)) { 243 if (Dart_IsError(result)) {
233 Free(); 244 Free();
234 return result; 245 return result;
235 } 246 }
236 for (BufferListNode* current = head_; current != NULL; 247 for (BufferListNode* current = head_; current != NULL;
237 current = current->next_) { 248 current = current->next()) {
238 intptr_t to_copy = dart::Utils::Minimum(data_size_, kBufferSize); 249 intptr_t to_copy = dart::Utils::Minimum(data_size_, kBufferSize);
239 memmove(buffer + buffer_position, current->data_, to_copy); 250 memmove(buffer + buffer_position, current->data(), to_copy);
240 buffer_position += to_copy; 251 buffer_position += to_copy;
241 data_size_ -= to_copy; 252 data_size_ -= to_copy;
242 } 253 }
243 ASSERT(data_size_ == 0); 254 ASSERT(data_size_ == 0);
244 Free(); 255 Free();
245 return result; 256 return result;
246 } 257 }
247 258
259 #if defined(DEBUG)
260 bool IsEmpty() const { return (head_ == NULL) && (tail_ == NULL); }
261 #endif
262
248 protected: 263 protected:
249 void Allocate() { 264 bool Allocate() {
250 ASSERT(free_size_ == 0); 265 ASSERT(free_size_ == 0);
251 BufferListNode* node = new BufferListNode(kBufferSize); 266 BufferListNode* node = new BufferListNode(kBufferSize);
267 if ((node == NULL) || !node->Valid()) {
268 // Failed to allocate a buffer for the node.
269 delete node;
270 return false;
271 }
252 if (head_ == NULL) { 272 if (head_ == NULL) {
253 head_ = node; 273 head_ = node;
254 tail_ = node; 274 tail_ = node;
255 } else { 275 } else {
256 ASSERT(tail_->next_ == NULL); 276 ASSERT(tail_->next() == NULL);
257 tail_->next_ = node; 277 tail_->set_next(node);
258 tail_ = node; 278 tail_ = node;
259 } 279 }
260 free_size_ = kBufferSize; 280 free_size_ = kBufferSize;
281 return true;
261 } 282 }
262 283
263 void Free() { 284 void Free() {
264 BufferListNode* current = head_; 285 BufferListNode* current = head_;
265 while (current != NULL) { 286 while (current != NULL) {
266 BufferListNode* tmp = current; 287 BufferListNode* tmp = current;
267 current = current->next_; 288 current = current->next();
268 delete tmp; 289 delete tmp;
269 } 290 }
270 head_ = NULL; 291 head_ = NULL;
271 tail_ = NULL; 292 tail_ = NULL;
272 data_size_ = 0; 293 data_size_ = 0;
273 free_size_ = 0; 294 free_size_ = 0;
274 } 295 }
275 296
276 // Returns the address of the first byte in the free space. 297 // Returns the address of the first byte in the free space.
277 uint8_t* FreeSpaceAddress() { 298 uint8_t* FreeSpaceAddress() {
278 return tail_->data_ + (kBufferSize - free_size_); 299 return tail_->data() + (kBufferSize - free_size_);
279 } 300 }
280 301
302 intptr_t data_size() const { return data_size_; }
303 void set_data_size(intptr_t size) { data_size_ = size; }
304
305 intptr_t free_size() const { return free_size_; }
306 void set_free_size(intptr_t size) { free_size_ = size; }
307
308 BufferListNode* head() const { return head_; }
309 BufferListNode* tail() const { return tail_; }
310
311 private:
281 // Linked list for data collected. 312 // Linked list for data collected.
282 BufferListNode* head_; 313 BufferListNode* head_;
283 BufferListNode* tail_; 314 BufferListNode* tail_;
284 315
285 // Number of bytes of data collected in the linked list. 316 // Number of bytes of data collected in the linked list.
286 intptr_t data_size_; 317 intptr_t data_size_;
287 318
288 // Number of free bytes in the last node in the list. 319 // Number of free bytes in the last node in the list.
289 intptr_t free_size_; 320 intptr_t free_size_;
290 321
291 private:
292 DISALLOW_COPY_AND_ASSIGN(BufferListBase); 322 DISALLOW_COPY_AND_ASSIGN(BufferListBase);
293 }; 323 };
294 324
325 #if defined(TARGET_OS_ANDROID) || defined(TARGET_OS_FUCHSIA) || \
326 defined(TARGET_OS_LINUX) || defined(TARGET_OS_MACOS)
327 class BufferList : public BufferListBase {
328 public:
329 BufferList() {}
330
331 bool Read(int fd, intptr_t available) {
332 // Read all available bytes.
333 while (available > 0) {
334 if (free_size() == 0) {
335 if (!Allocate()) {
336 errno = ENOMEM;
337 return false;
338 }
339 }
340 ASSERT(free_size() > 0);
341 ASSERT(free_size() <= kBufferSize);
342 intptr_t block_size = dart::Utils::Minimum(free_size(), available);
343 #if defined(TARGET_OS_FUCHSIA)
344 intptr_t bytes = NO_RETRY_EXPECTED(
345 read(fd, reinterpret_cast<void*>(FreeSpaceAddress()), block_size));
346 #else
347 intptr_t bytes = TEMP_FAILURE_RETRY(
348 read(fd, reinterpret_cast<void*>(FreeSpaceAddress()), block_size));
349 #endif // defined(TARGET_OS_FUCHSIA)
350 if (bytes < 0) {
351 return false;
352 }
353 set_data_size(data_size() + bytes);
354 set_free_size(free_size() - bytes);
355 available -= bytes;
356 }
357 return true;
358 }
359
360 private:
361 DISALLOW_COPY_AND_ASSIGN(BufferList);
362 };
363 #endif // defined(TARGET_OS_ANDROID) ...
364
295 } // namespace bin 365 } // namespace bin
296 } // namespace dart 366 } // namespace dart
297 367
298 #endif // RUNTIME_BIN_PROCESS_H_ 368 #endif // RUNTIME_BIN_PROCESS_H_
OLDNEW
« no previous file with comments | « no previous file | runtime/bin/process_android.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698