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

Unified Diff: runtime/bin/process_linux.cc

Issue 22827002: Change the allocation of the stdout and stderr collected by Process.runSync (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Minor fixes 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/bin/process.cc ('k') | runtime/bin/process_macos.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/bin/process_linux.cc
diff --git a/runtime/bin/process_linux.cc b/runtime/bin/process_linux.cc
index 52f99b6cab8ad9c4c5fa63847fe14e7416acab1c..0dfca8928f10d5e00a485ade3eceb5e10a31c13d 100644
--- a/runtime/bin/process_linux.cc
+++ b/runtime/bin/process_linux.cc
@@ -21,6 +21,7 @@
#include "bin/log.h"
#include "bin/thread.h"
+
extern char **environ;
@@ -568,23 +569,27 @@ int Process::Start(const char* path,
}
-static bool ReadProcessBuffer(uint8_t** buffer,
- intptr_t* buffer_length,
- intptr_t available,
- int fd) {
- uint8_t* tmp = new uint8_t[*buffer_length + available];
- if (tmp == NULL) FATAL("Allocation failed");
- memmove(tmp, *buffer, *buffer_length);
- delete[] *buffer;
- *buffer = tmp;
- intptr_t bytes = TEMP_FAILURE_RETRY(read(
- fd,
- reinterpret_cast<void*>(*buffer + *buffer_length),
- available));
- if (bytes < 0) return false;
- *buffer_length += bytes;
- return true;
-}
+class BufferList: public BufferListBase {
+ public:
+ bool Read(int fd, intptr_t available) {
+ // Read all available bytes.
+ while (available > 0) {
+ if (free_size_ == 0) Allocate();
+ ASSERT(free_size_ > 0);
+ ASSERT(free_size_ <= kBufferSize);
+ intptr_t block_size = dart::Utils::Minimum(free_size_, available);
+ intptr_t bytes = TEMP_FAILURE_RETRY(read(
+ fd,
+ reinterpret_cast<void*>(tail_->data_ + (kBufferSize - free_size_)),
+ block_size));
+ if (bytes < 0) return false;
+ data_size_ += bytes;
+ free_size_ -= bytes;
+ available -= bytes;
+ }
+ return true;
+ }
+};
static bool CloseProcessBuffers(struct pollfd fds[3]) {
@@ -606,10 +611,11 @@ bool Process::Wait(intptr_t pid,
// Close input to the process right away.
VOID_TEMP_FAILURE_RETRY(close(in));
- uint8_t* out_data = NULL;
- intptr_t out_data_length = 0;
- uint8_t* err_data = NULL;
- intptr_t err_data_length = 0;
+ // There is no return from this function using Dart_PropagateError
+ // as memory used by the buffer lists is freed through their
+ // destructors.
+ BufferList out_data;
+ BufferList err_data;
union {
uint8_t bytes[8];
int32_t ints[2];
@@ -630,20 +636,22 @@ bool Process::Wait(intptr_t pid,
if (TEMP_FAILURE_RETRY(poll(fds, alive, -1)) <= 0) {
return CloseProcessBuffers(fds);
}
+
+ // Process incoming data.
for (int i = 0; i < alive; i++) {
if (fds[i].revents & POLLIN) {
intptr_t avail = FDUtils::AvailableBytes(fds[i].fd);
if (fds[i].fd == out) {
- if (!ReadProcessBuffer(&out_data, &out_data_length, avail, out)) {
+ if (!out_data.Read(out, avail)) {
return CloseProcessBuffers(fds);
}
} else if (fds[i].fd == err) {
- if (!ReadProcessBuffer(&err_data, &err_data_length, avail, err)) {
+ if (!err_data.Read(err, avail)) {
return CloseProcessBuffers(fds);
}
} else if (fds[i].fd == exit_event) {
if (avail == 8) {
- intptr_t b = TEMP_FAILURE_RETRY(read(fds[i].fd,
+ intptr_t b = TEMP_FAILURE_RETRY(read(exit_event,
exit_code_data.bytes, 8));
if (b != 8) {
return CloseProcessBuffers(fds);
@@ -652,9 +660,11 @@ bool Process::Wait(intptr_t pid,
} else {
UNREACHABLE();
}
- continue;
}
+ }
+ // Process closed.
+ for (int i = 0; i < alive; i++) {
if (fds[i].revents & POLLHUP) {
VOID_TEMP_FAILURE_RETRY(close(fds[i].fd));
alive--;
@@ -666,8 +676,8 @@ bool Process::Wait(intptr_t pid,
}
// All handles closed and all data read.
- result->SetStdoutData(out_data, out_data_length);
- result->SetStderrData(err_data, err_data_length);
+ result->set_stdout_data(out_data.GetData());
+ result->set_stderr_data(err_data.GetData());
// Calculate the exit code.
intptr_t exit_code = exit_code_data.ints[0];
« no previous file with comments | « runtime/bin/process.cc ('k') | runtime/bin/process_macos.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698