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

Unified Diff: runtime/bin/eventhandler_win.cc

Issue 25631005: Reuse thread when writing stdout/stderr on Windows. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 2 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 | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/bin/eventhandler_win.cc
diff --git a/runtime/bin/eventhandler_win.cc b/runtime/bin/eventhandler_win.cc
index 59b22077d4d5a8f67257595bb9c41face06fa7a4..16e195823a859ae6d47c6f644b0e49956cf513b7 100644
--- a/runtime/bin/eventhandler_win.cc
+++ b/runtime/bin/eventhandler_win.cc
@@ -20,6 +20,7 @@
#include "bin/socket.h"
#include "bin/utils.h"
#include "platform/thread.h"
+#include "vm/thread.h"
namespace dart {
@@ -560,9 +561,27 @@ int Handle::Read(void* buffer, int num_bytes) {
}
Søren Gjesse 2013/10/02 08:49:22 Please add these static variables to the Windows E
Anders Johnsen 2013/10/02 10:16:59 Done.
+static Monitor* write_monitor = new Monitor();
+static bool write_thread_exists = false;
+static bool write_thread_running = false;
+static Handle* write_handle = NULL;
+
static unsigned int __stdcall WriteFileThread(void* args) {
- Handle* handle = reinterpret_cast<Handle*>(args);
- handle->WriteSyncCompleteAsync();
+ MonitorLocker locker(write_monitor);
+ write_thread_running = true;
+ // Notify we have started.
+ locker.Notify();
+
+ while (write_thread_running) {
+ locker.Wait(Monitor::kNoTimeout);
+ if (write_handle) {
+ // We woke up and had a handle. Complete it.
+ write_handle->WriteSyncCompleteAsync();
+ write_handle = NULL;
+ }
+ }
+ write_thread_exists = false;
+ locker.Notify();
return 0;
}
@@ -606,24 +625,43 @@ int Handle::Write(const void* buffer, int num_bytes) {
return num_bytes;
} else {
// In the case of stdout and stderr, OverlappedIO is not supported.
- // Here we'll instead spawn a new thread for each write, to make it async.
+ // Here we'll instead use a thread, to make it async.
// This code is actually never exposed to the user, as stdout and stderr is
// not available as a RawSocket, but only wrapped in a Socket.
// Note that we return '0', unless a thread have already completed a write.
- // TODO(ajohnsen): Don't spawn a new thread per write. Issue 13541.
if (thread_wrote_ > 0) {
if (num_bytes > thread_wrote_) num_bytes = thread_wrote_;
thread_wrote_ -= num_bytes;
return num_bytes;
}
- pending_write_ = OverlappedBuffer::AllocateWriteBuffer(num_bytes);
- pending_write_->Write(buffer, num_bytes);
- // Completing asynchronously through thread.
- uint32_t tid;
- uintptr_t thread_handle =
- _beginthreadex(NULL, 32 * 1024, WriteFileThread, this, 0, &tid);
- if (thread_handle == -1) {
- FATAL("Failed to start write file thread");
+ // Double-checked locking, to avoid taking the lock in most cases.
Søren Gjesse 2013/10/02 08:49:22 You need to hold the lock before accessing shared
Anders Johnsen 2013/10/02 10:16:59 Done.
+ if (!write_thread_exists) {
+ MonitorLocker locker(write_monitor);
+ if (!write_thread_exists) {
+ write_thread_exists = true;
+ uint32_t tid;
+ uintptr_t thread_handle =
+ _beginthreadex(NULL, 32 * 1024, WriteFileThread, this, 0, &tid);
+ // Completing asynchronously through thread.
+ if (thread_handle == -1) {
+ FATAL("Failed to start write file thread");
+ }
+ while (!write_thread_running) {
+ // Wait until we the thread is running.
+ locker.Wait(Monitor::kNoTimeout);
+ }
+ }
+ }
+ // Double-checked locking, to avoid taking the lock in most cases.
+ if (write_handle == NULL) {
+ MonitorLocker locker(write_monitor);
+ if (write_handle == NULL) {
+ // Create buffer and notify thread about the new handle.
+ pending_write_ = OverlappedBuffer::AllocateWriteBuffer(num_bytes);
+ pending_write_->Write(buffer, num_bytes);
+ write_handle = this;
+ locker.Notify();
+ }
}
return 0;
}
@@ -999,6 +1037,15 @@ EventHandlerImplementation::EventHandlerImplementation() {
EventHandlerImplementation::~EventHandlerImplementation() {
Søren Gjesse 2013/10/02 08:49:22 Take the lock before looking at shared data.
Anders Johnsen 2013/10/02 10:16:59 Done.
+ if (write_thread_exists) {
+ ASSERT(write_handle == NULL);
+ MonitorLocker locker(write_monitor);
+ write_thread_running = false;
+ locker.Notify();
+ while (write_thread_exists) {
+ locker.Wait(Monitor::kNoTimeout);
+ }
+ }
CloseHandle(completion_port_);
}
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698