| Index: runtime/bin/process_win.cc
|
| diff --git a/runtime/bin/process_win.cc b/runtime/bin/process_win.cc
|
| index 6607e839d1bf86f402c8523f1d3d9418aaee25b6..106361329cb05e9fe20aaefef3bcc10d7950cc05 100644
|
| --- a/runtime/bin/process_win.cc
|
| +++ b/runtime/bin/process_win.cc
|
| @@ -642,16 +642,51 @@ int Process::Start(const char* path,
|
| }
|
|
|
|
|
| -class OverlappedHandle {
|
| +class BufferList: public BufferListBase {
|
| public:
|
| - static const int kBufferSize = 16 * 1024;
|
| + BufferList() : read_pending_(true) { }
|
| +
|
| + void DataRead(intptr_t size) {
|
| + ASSERT(read_pending_ == true);
|
| + data_size_ += size;
|
| + free_size_ -= size;
|
| + ASSERT(free_size_ >= 0);
|
| + read_pending_ = false;
|
| + }
|
| +
|
| + void GetReadBuffer(uint8_t** buffer, intptr_t* size) {
|
| + ASSERT(!read_pending_);
|
| + if (free_size_ == 0) Allocate();
|
| + ASSERT(free_size_ > 0);
|
| + ASSERT(free_size_ <= kBufferSize);
|
| + *buffer = tail_->data_ + (kBufferSize - free_size_);
|
| + *size = free_size_;
|
| + read_pending_ = true;
|
| + }
|
| +
|
| + intptr_t GetDataSize() {
|
| + return data_size_;
|
| + }
|
| +
|
| + uint8_t* GetDataBuffer() {
|
| + return head_->data_;
|
| + }
|
| +
|
| + void FreeDataBuffer() {
|
| + Free();
|
| + }
|
| +
|
| + private:
|
| + bool read_pending_;
|
| +};
|
| +
|
|
|
| +class OverlappedHandle {
|
| + public:
|
| void Init(HANDLE handle, HANDLE event) {
|
| handle_ = handle;
|
| event_ = event;
|
| ClearOverlapped();
|
| - data_ = NULL;
|
| - data_length_ = 0;
|
| }
|
|
|
| bool HasEvent(HANDLE event) {
|
| @@ -661,20 +696,38 @@ class OverlappedHandle {
|
| bool Read() {
|
| // Get the data read as a rasult of a completed overlapped operation.
|
| if (overlapped_.InternalHigh > 0) {
|
| - AddData(overlapped_.InternalHigh);
|
| + buffer_.DataRead(overlapped_.InternalHigh);
|
| + } else {
|
| + buffer_.DataRead(0);
|
| }
|
|
|
| // Keep reading until error or pending operation.
|
| while (true) {
|
| ClearOverlapped();
|
| - BOOL ok = ReadFile(handle_, buffer_, kBufferSize, NULL, &overlapped_);
|
| + uint8_t* buffer;
|
| + intptr_t buffer_size;
|
| + buffer_.GetReadBuffer(&buffer, &buffer_size);
|
| + BOOL ok = ReadFile(handle_, buffer, buffer_size, NULL, &overlapped_);
|
| if (!ok) return GetLastError() == ERROR_IO_PENDING;
|
| - AddData(overlapped_.InternalHigh);
|
| + buffer_.DataRead(overlapped_.InternalHigh);
|
| }
|
| }
|
|
|
| - uint8_t* data() { return data_; }
|
| - intptr_t data_length() { return data_length_; }
|
| + Dart_Handle GetData() {
|
| + return buffer_.GetData();
|
| + }
|
| +
|
| + intptr_t GetDataSize() {
|
| + return buffer_.GetDataSize();
|
| + }
|
| +
|
| + uint8_t* GetDataBuffer() {
|
| + return buffer_.GetDataBuffer();
|
| + }
|
| +
|
| + void FreeDataBuffer() {
|
| + return buffer_.FreeDataBuffer();
|
| + }
|
|
|
| void Close() {
|
| CloseHandle(handle_);
|
| @@ -683,39 +736,16 @@ class OverlappedHandle {
|
| overlapped_.hEvent = INVALID_HANDLE_VALUE;
|
| }
|
|
|
| - void FreeData() {
|
| - free(data_);
|
| - data_ = NULL;
|
| - data_length_ = 0;
|
| - }
|
| -
|
| - void Destroy() {
|
| - Close();
|
| - FreeData();
|
| - }
|
| -
|
| private:
|
| void ClearOverlapped() {
|
| memset(&overlapped_, 0, sizeof(overlapped_));
|
| overlapped_.hEvent = event_;
|
| }
|
|
|
| - void AddData(DWORD length) {
|
| - uint8_t* tmp = new uint8_t[data_length_ + length];
|
| - if (tmp == NULL) FATAL("Allocation failed");
|
| - memmove(tmp, data_, data_length_);
|
| - memmove(tmp + data_length_, buffer_, length);
|
| - delete[] data_;
|
| - data_ = tmp;
|
| - data_length_ += length;
|
| - }
|
| -
|
| OVERLAPPED overlapped_;
|
| HANDLE handle_;
|
| HANDLE event_;
|
| - char buffer_[kBufferSize];
|
| - uint8_t* data_;
|
| - intptr_t data_length_;
|
| + BufferList buffer_;
|
|
|
| DISALLOW_ALLOCATION();
|
| };
|
| @@ -748,7 +778,6 @@ bool Process::Wait(intptr_t pid,
|
|
|
| // Setup the structure for handling overlapped IO.
|
| OverlappedHandle oh[kHandles];
|
| - memset(&oh, 0, sizeof(oh));
|
| oh[0].Init(stdout_handle->handle(), events[0]);
|
| oh[1].Init(stderr_handle->handle(), events[1]);
|
| oh[2].Init(exit_handle->handle(), events[2]);
|
| @@ -773,9 +802,9 @@ bool Process::Wait(intptr_t pid,
|
| }
|
| } else if (err != ERROR_IO_PENDING) {
|
| DWORD e = GetLastError();
|
| - oh[0].Destroy();
|
| - oh[1].Destroy();
|
| - oh[2].Destroy();
|
| + oh[0].Close();
|
| + oh[1].Close();
|
| + oh[2].Close();
|
| SetLastError(e);
|
| return false;
|
| }
|
| @@ -786,14 +815,14 @@ bool Process::Wait(intptr_t pid,
|
| }
|
|
|
| // All handles closed and all data read.
|
| - result->SetStdoutData(oh[0].data(), oh[0].data_length());
|
| - result->SetStderrData(oh[1].data(), oh[1].data_length());
|
| + result->set_stdout_data(oh[0].GetData());
|
| + result->set_stderr_data(oh[1].GetData());
|
|
|
| // Calculate the exit code.
|
| - ASSERT(oh[2].data_length() == 8);
|
| + ASSERT(oh[2].GetDataSize() == 8);
|
| uint32_t exit[2];
|
| - memcpy(&exit, oh[2].data(), sizeof(exit));
|
| - oh[2].FreeData();
|
| + memcpy(&exit, oh[2].GetDataBuffer(), sizeof(exit));
|
| + oh[2].FreeDataBuffer();
|
| intptr_t exit_code = exit[0];
|
| intptr_t negative = exit[1];
|
| if (negative) exit_code = -exit_code;
|
|
|