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

Unified Diff: runtime/bin/process_win.cc

Issue 9307033: Revert "Changes to the process implementation." (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 11 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_macos.cc ('k') | tools/testing/bin/linux/dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/bin/process_win.cc
diff --git a/runtime/bin/process_win.cc b/runtime/bin/process_win.cc
index 78084a2d2e55b573f74e403a861fc5f537e3d6e5..8401ef6de62ad6c5672de76e319503e7a3272f01 100644
--- a/runtime/bin/process_win.cc
+++ b/runtime/bin/process_win.cc
@@ -7,17 +7,11 @@
#include "bin/builtin.h"
#include "bin/process.h"
#include "bin/eventhandler.h"
-#include "bin/thread.h"
#include "platform/globals.h"
static const int kReadHandle = 0;
static const int kWriteHandle = 1;
-
-// ProcessInfo is used to map a process id to the process handle and
-// the pipe used to communicate the exit code of the process to Dart.
-// ProcessInfo objects are kept in the static singly-linked
-// ProcessInfoList.
class ProcessInfo {
public:
ProcessInfo(DWORD process_id, HANDLE process_handle, HANDLE exit_pipe)
@@ -25,18 +19,7 @@ class ProcessInfo {
process_handle_(process_handle),
exit_pipe_(exit_pipe) { }
- ~ProcessInfo() {
- BOOL success = CloseHandle(process_handle_);
- if (!success) {
- FATAL("Failed to close process handle");
- }
- success = CloseHandle(exit_pipe_);
- if (!success) {
- FATAL("Failed to close process exit code pipe");
- }
- }
-
- DWORD pid() { return process_id_; }
+ intptr_t pid() { return process_id_; }
HANDLE process_handle() { return process_handle_; }
HANDLE exit_pipe() { return exit_pipe_; }
ProcessInfo* next() { return next_; }
@@ -50,249 +33,44 @@ class ProcessInfo {
};
-// Singly-linked list of ProcessInfo objects for all active processes
-// started from Dart.
-class ProcessInfoList {
- public:
- static void AddProcess(DWORD pid, HANDLE handle, HANDLE pipe) {
- MutexLocker locker(&mutex_);
- ProcessInfo* info = new ProcessInfo(pid, handle, pipe);
- info->set_next(active_processes_);
- active_processes_ = info;
- ++number_of_processes_;
- }
-
- static bool LookupProcess(DWORD pid, HANDLE* handle, HANDLE* pipe) {
- MutexLocker locker(&mutex_);
- ProcessInfo* current = active_processes_;
- while (current != NULL) {
- if (current->pid() == pid) {
- *handle = current->process_handle();
- *pipe = current->exit_pipe();
- return true;
- }
- current = current->next();
- }
- return false;
- }
-
- static DWORD LookupProcessByHandle(HANDLE handle, DWORD* pid, HANDLE* pipe) {
- MutexLocker locker(&mutex_);
- ProcessInfo* current = active_processes_;
- while (current != NULL) {
- if (current->process_handle() == handle) {
- *pid = current->pid();
- *pipe = current->exit_pipe();
- return true;
- }
- current = current->next();
- }
- return false;
- }
-
- static void RemoveProcess(DWORD pid) {
- MutexLocker locker(&mutex_);
- ProcessInfo* prev = NULL;
- ProcessInfo* current = active_processes_;
- while (current != NULL) {
- if (current->pid() == pid) {
- if (prev == NULL) {
- active_processes_ = current->next();
- } else {
- prev->set_next(current->next());
- }
- delete current;
- --number_of_processes_;
- return;
- }
- prev = current;
- current = current->next();
- }
- }
-
- static void GetHandleArray(HANDLE** handles,
- DWORD* number_of_handles,
- intptr_t prefix_size) {
- ASSERT(prefix_size >= 0);
- *number_of_handles = prefix_size + number_of_processes_;
- *handles = new HANDLE[*number_of_handles];
- intptr_t i = prefix_size;
- ProcessInfo* current = active_processes_;
- while (current != NULL) {
- (*handles)[i++] = current->process_handle();
- current = current->next();
- }
- ASSERT(i == *number_of_handles);
- }
-
- private:
- // Number of processes currently in the list.
- static intptr_t number_of_processes_;
- // Linked list of ProcessInfo objects for all active processes
- // started from Dart code.
- static ProcessInfo* active_processes_;
- // Mutex protecting all accesses to the linked list of active
- // processes.
- static dart::Mutex mutex_;
-};
-
-
-intptr_t ProcessInfoList::number_of_processes_ = 0;
-ProcessInfo* ProcessInfoList::active_processes_ = NULL;
-dart::Mutex ProcessInfoList::mutex_;
-
-
-// The exit code handler sets up a separate thread which is waiting
-// for Dart process termination and process start. When a process
-// terminates the exit code is extracted and communicated to Dart
-// through the event loop.
-class ExitCodeHandler {
- public:
- // Ensure that the ExitCodeHandler has been initialized.
- static bool EnsureInitialized() {
- // Multiple isolates could be starting processes at the same
- // time. Make sure that only one of them initializes the
- // ExitCodeHandler.
- MutexLocker locker(&mutex_);
- if (initialized_) {
- return true;
- }
-
- // Allocate an event object to be signaled when new processes are
- // added.
- wake_up_event_ = CreateEvent(NULL, TRUE, FALSE, NULL);
- if (wake_up_event_ == NULL) {
- return false;
- }
+ProcessInfo* active_processes = NULL;
- // Start thread that waits for the process-addition handle as well
- // as all process handles for all active processes.
- new dart::Thread(ExitCodeHandlerEntry,
- reinterpret_cast<uword>(wake_up_event_));
- // Thread started and the ExitCodeHandler is initialized.
- initialized_ = true;
- return true;
- }
+static void AddProcess(ProcessInfo* process) {
+ process->set_next(active_processes);
+ active_processes = process;
+}
- static void Shutdown() {
- MutexLocker locker(&mutex_);
- if (!initialized_) {
- return;
- }
- terminating_ = true;
- BOOL success = SetEvent(wake_up_event_);
- if (!success) {
- FATAL("Failed to set wake-up event for exit code handler shutdown");
- }
- }
- static void ProcessAdded() {
- MutexLocker locker(&mutex_);
- BOOL success = SetEvent(wake_up_event_);
- if (!success) {
- FATAL("Failed to set the process addition wake-up event");
+static ProcessInfo* LookupProcess(intptr_t pid) {
+ ProcessInfo* current = active_processes;
+ while (current != NULL) {
+ if (current->pid() == pid) {
+ return current;
}
+ current = current->next();
}
+ return NULL;
+}
- static bool Terminating() {
- MutexLocker locker(&mutex_);
- return terminating_;
- }
-
- private:
- // Entry point for the exit code handler thread started by the
- // ExitCodeHandler.
- static void ExitCodeHandlerEntry(uword param) {
- HANDLE wake_up_event = reinterpret_cast<HANDLE>(param);
-
- while (true) {
- // Get the list of handles to wait for. Allocate a prefix of one
- // extra handle for the 'process added' event object.
- HANDLE* handles;
- DWORD number_of_handles;
- intptr_t prefix_size = 1;
- ProcessInfoList::GetHandleArray(&handles,
- &number_of_handles,
- prefix_size);
- handles[0] = wake_up_event;
-
- // TODO(1450): support more than 63 processes on Windows.
- if (number_of_handles > MAXIMUM_WAIT_OBJECTS) {
- FATAL1("Only %d processes supported on Windows at this point\n",
- MAXIMUM_WAIT_OBJECTS - 1);
- }
-
- // Wait for the handles.
- DWORD result =
- WaitForMultipleObjects(number_of_handles, handles, FALSE, INFINITE);
- if (result == WAIT_FAILED) {
- FATAL("Failed to wait for multiple objects for exit code handling");
- }
- if (result == 0) {
- // If the result is 0 the thread woke up because of process
- // addition or because the ExitCodeHandler is being shut down.
- if (ExitCodeHandler::Terminating()) {
- BOOL success = CloseHandle(wake_up_event_);
- if (!success) {
- FATAL("Failed to clse the wake-up event handle");
- }
- return;
- }
- // This was an addition, we reset the wake up event so we can
- // get signalled on further additions.
- BOOL success = ResetEvent(wake_up_event);
- if (!success) {
- FATAL("Failed to reset process addition wake-up event");
- }
+static void RemoveProcess(intptr_t pid) {
+ ProcessInfo* prev = NULL;
+ ProcessInfo* current = active_processes;
+ while (current != NULL) {
+ if (current->pid() == pid) {
+ if (prev == NULL) {
+ active_processes = current->next();
} else {
- // The result is the index of the process that was
- // signalled. Get its exit code and communicate it to Dart.
- int exit_code;
- BOOL ok = GetExitCodeProcess(handles[result],
- reinterpret_cast<DWORD*>(&exit_code));
- if (!ok) {
- FATAL1("GetExitCodeProcess failed %d\n", GetLastError());
- }
- int negative = 0;
- if (exit_code < 0) {
- exit_code = abs(exit_code);
- negative = 1;
- }
-
- DWORD pid;
- HANDLE exit_pipe;
- bool success = ProcessInfoList::LookupProcessByHandle(handles[result],
- &pid,
- &exit_pipe);
- if (!success) {
- FATAL("Failed to lookup pid and exit pipe from process handle");
- }
- int message[2] = { exit_code, negative };
- DWORD written;
- ok = WriteFile(exit_pipe, message, sizeof(message), &written, NULL);
- if (!ok || written != sizeof(message)) {
- FATAL1("WriteFile to process exit code pipe failed %d\n",
- GetLastError());
- }
- ProcessInfoList::RemoveProcess(pid);
+ prev->set_next(current->next());
}
- delete[] handles;
+ delete current;
+ return;
}
+ prev = current;
+ current = current->next();
}
-
- static dart::Mutex mutex_;
- static bool initialized_;
- static bool terminating_;
- static HANDLE wake_up_event_;
-};
-
-
-dart::Mutex ExitCodeHandler::mutex_;
-bool ExitCodeHandler::initialized_ = false;
-bool ExitCodeHandler::terminating_ = false;
-HANDLE ExitCodeHandler::wake_up_event_ = 0;
+}
// Types of pipes to create.
@@ -423,6 +201,31 @@ static int SetOsErrorMessage(char* os_error_message,
}
+static unsigned int __stdcall TerminationWaitThread(void* args) {
+ ProcessInfo* process = reinterpret_cast<ProcessInfo*>(args);
+ WaitForSingleObject(process->process_handle(), INFINITE);
+ int exit_code;
+ BOOL ok = GetExitCodeProcess(process->process_handle(),
+ reinterpret_cast<DWORD*>(&exit_code));
+ if (!ok) {
+ fprintf(stderr, "GetExitCodeProcess failed %d\n", GetLastError());
+ }
+ int negative = 0;
+ if (exit_code < 0) {
+ exit_code = abs(exit_code);
+ negative = 1;
+ }
+ int message[3] = { process->pid(), exit_code, negative };
+ DWORD written;
+ ok = WriteFile(
+ process->exit_pipe(), message, sizeof(message), &written, NULL);
+ if (!ok || written != sizeof(message)) {
+ fprintf(stderr, "WriteFile failed %d\n", GetLastError());
+ }
+ return 0;
+}
+
+
int Process::Start(const char* path,
char* arguments[],
intptr_t arguments_length,
@@ -434,14 +237,6 @@ int Process::Start(const char* path,
intptr_t* exit_handler,
char* os_error_message,
int os_error_message_len) {
- // Ensure that the process exit handler thread has been started.
- bool initialized = ExitCodeHandler::EnsureInitialized();
- if (!initialized) {
- int error_code = SetOsErrorMessage(os_error_message, os_error_message_len);
- fprintf(stderr, "Failed to initialize ExitCodeHandler: %d\n", error_code);
- return error_code;
- }
-
HANDLE stdin_handles[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE };
HANDLE stdout_handles[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE };
HANDLE stderr_handles[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE };
@@ -566,10 +361,19 @@ int Process::Start(const char* path,
return error_code;
}
- ProcessInfoList::AddProcess(process_info.dwProcessId,
- process_info.hProcess,
- exit_handles[kWriteHandle]);
- ExitCodeHandler::ProcessAdded();
+ ProcessInfo* process = new ProcessInfo(process_info.dwProcessId,
+ process_info.hProcess,
+ exit_handles[kWriteHandle]);
+ AddProcess(process);
+
+ // TODO(sgjesse): Don't use a separate thread for waiting for each process to
+ // terminate.
+ uint32_t tid;
+ uintptr_t thread_handle =
+ _beginthreadex(NULL, 32 * 1024, TerminationWaitThread, process, 0, &tid);
+ if (thread_handle == -1) {
+ FATAL("Failed to start process termination wait thread");
+ }
// Connect the three std streams.
FileHandle* stdin_handle = new FileHandle(stdin_handles[kWriteHandle]);
@@ -587,25 +391,24 @@ int Process::Start(const char* path,
CloseHandle(process_info.hThread);
// Return process id.
- *id = process_info.dwProcessId;
+ *id = process->pid();
return 0;
}
bool Process::Kill(intptr_t id) {
- HANDLE process_handle;
- HANDLE exit_pipe;
- bool success =
- ProcessInfoList::LookupProcess(id, &process_handle, &exit_pipe);
- ASSERT(success);
- BOOL result = TerminateProcess(process_handle, -1);
- if (!result) {
- return false;
+ ProcessInfo* process = LookupProcess(id);
+ ASSERT(process != NULL);
+ if (process != NULL) {
+ BOOL result = TerminateProcess(process->process_handle(), -1);
+ if (result == 0) {
+ return false;
+ }
}
return true;
}
-void Process::TerminateExitCodeHandler() {
- ExitCodeHandler::Shutdown();
+void Process::Exit(intptr_t id) {
+ RemoveProcess(id);
}
« no previous file with comments | « runtime/bin/process_macos.cc ('k') | tools/testing/bin/linux/dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698