Index: runtime/bin/process_fuchsia.cc |
diff --git a/runtime/bin/process_fuchsia.cc b/runtime/bin/process_fuchsia.cc |
index 14f3faa85e1682c9590941623bb21fc45ec7ce8a..9d55e33dc8120cbb17e71e2d07bcf4aa4ace00f7 100644 |
--- a/runtime/bin/process_fuchsia.cc |
+++ b/runtime/bin/process_fuchsia.cc |
@@ -17,6 +17,8 @@ |
#include <magenta/status.h> |
#include <magenta/syscalls.h> |
#include <magenta/syscalls/object.h> |
+#include <magenta/types.h> |
+#include <mxio/private.h> |
#include <mxio/util.h> |
#include <pthread.h> |
#include <stdbool.h> |
@@ -77,7 +79,6 @@ class ProcessInfo { |
DISALLOW_COPY_AND_ASSIGN(ProcessInfo); |
}; |
- |
// Singly-linked list of ProcessInfo objects for all active processes |
// started from Dart. |
class ProcessInfoList { |
@@ -425,12 +426,10 @@ void Process::TerminateExitCodeHandler() { |
ExitCodeHandler::Terminate(); |
} |
- |
zra
2017/05/26 16:13:22
Dart VM style is two newlines between top-level fu
jamesr1
2017/05/27 00:14:09
Turns out I wasn't reading your .clang-format file
|
intptr_t Process::CurrentProcessId() { |
return static_cast<intptr_t>(getpid()); |
} |
- |
int64_t Process::CurrentRSS() { |
mx_info_task_stats_t task_stats; |
mx_handle_t process = mx_process_self(); |
@@ -444,27 +443,56 @@ int64_t Process::CurrentRSS() { |
return task_stats.mem_committed_bytes; |
} |
- |
int64_t Process::MaxRSS() { |
// There is currently no way to get the high watermark value on Fuchsia, so |
// just return the current RSS value. |
return CurrentRSS(); |
} |
- |
static bool ProcessWaitCleanup(intptr_t out, |
intptr_t err, |
- intptr_t exit_event, |
- intptr_t epoll_fd) { |
+ intptr_t exit_event) { |
int e = errno; |
VOID_NO_RETRY_EXPECTED(close(out)); |
VOID_NO_RETRY_EXPECTED(close(err)); |
VOID_NO_RETRY_EXPECTED(close(exit_event)); |
- VOID_NO_RETRY_EXPECTED(close(epoll_fd)); |
errno = e; |
return false; |
} |
+class MxioWaitEntry { |
+ public: |
+ explicit MxioWaitEntry(int fd) : mxio_(__mxio_fd_to_io(fd)) {} |
+ ~MxioWaitEntry() { Cancel(); } |
+ |
+ void WaitBegin(mx_wait_item_t* wait_item) { |
+ if (mxio_ == nullptr) { |
zra
2017/05/26 16:13:22
To be consistent with the rest of the VM, please u
jamesr1
2017/05/27 00:14:10
done
|
+ *wait_item = {}; |
+ return; |
+ } |
+ |
+ __mxio_wait_begin(mxio_, EPOLLRDHUP | EPOLLIN, &wait_item->handle, |
+ &wait_item->waitfor); |
+ wait_item->pending = 0; |
+ } |
+ |
+ void WaitEnd(mx_wait_item_t* wait_item, uint32_t* event) { |
+ if (mxio_ == nullptr) { |
+ *event = 0; |
+ return; |
+ } |
+ __mxio_wait_end(mxio_, wait_item->pending, event); |
+ } |
+ |
+ void Cancel() { |
+ if (mxio_) |
zra
2017/05/26 16:13:22
if (mxio_ != NULL)
Also, please use curly braces
jamesr1
2017/05/27 00:14:10
done
|
+ __mxio_release(mxio_); |
+ mxio_ = nullptr; |
+ } |
+ |
+ private: |
+ mxio_t* mxio_; |
+}; |
zra
2017/05/26 16:13:22
Maybe DISALLOW_COPY_AND_ASSIGN(MxioWaitEntry) or D
jamesr1
2017/05/27 00:14:10
done
|
bool Process::Wait(intptr_t pid, |
intptr_t in, |
@@ -484,83 +512,58 @@ bool Process::Wait(intptr_t pid, |
int32_t ints[2]; |
} exit_code_data; |
- // The initial size passed to epoll_create is ignore on newer (>= |
- // 2.6.8) Linux versions |
- static const int kEpollInitialSize = 64; |
- int epoll_fd = NO_RETRY_EXPECTED(epoll_create(kEpollInitialSize)); |
- if (epoll_fd == -1) { |
- return ProcessWaitCleanup(out, err, exit_event, epoll_fd); |
- } |
- if (!FDUtils::SetCloseOnExec(epoll_fd)) { |
- return ProcessWaitCleanup(out, err, exit_event, epoll_fd); |
- } |
+ uint32_t events[3]; |
+ mx_wait_item_t wait_items[3]; |
zra
2017/05/26 16:13:22
const intptr_t kWaitItemsCount = 3;
jamesr1
2017/05/27 00:14:10
done
|
+ size_t active = 3; |
- struct epoll_event event; |
- event.events = EPOLLRDHUP | EPOLLIN; |
- event.data.fd = out; |
- int status = NO_RETRY_EXPECTED( |
- epoll_ctl(epoll_fd, EPOLL_CTL_ADD, out, &event)); |
- if (status == -1) { |
- return ProcessWaitCleanup(out, err, exit_event, epoll_fd); |
- } |
- event.data.fd = err; |
- status = NO_RETRY_EXPECTED( |
- epoll_ctl(epoll_fd, EPOLL_CTL_ADD, err, &event)); |
- if (status == -1) { |
- return ProcessWaitCleanup(out, err, exit_event, epoll_fd); |
- } |
- event.data.fd = exit_event; |
- status = NO_RETRY_EXPECTED( |
- epoll_ctl(epoll_fd, EPOLL_CTL_ADD, exit_event, &event)); |
- if (status == -1) { |
- return ProcessWaitCleanup(out, err, exit_event, epoll_fd); |
- } |
- intptr_t active = 3; |
+ MxioWaitEntry entries[3] = { |
+ MxioWaitEntry(out), MxioWaitEntry(err), MxioWaitEntry(exit_event), |
+ }; |
- static const intptr_t kMaxEvents = 16; |
- struct epoll_event events[kMaxEvents]; |
while (active > 0) { |
// TODO(US-109): When the epoll implementation is properly edge-triggered, |
// remove this sleep, which prevents the message queue from being |
// overwhelmed and leading to memory exhaustion. |
usleep(5000); |
zra
2017/05/26 16:13:22
This was copy-pasted from the eventhandler, but pr
jamesr1
2017/05/27 00:14:10
done
|
- intptr_t result = NO_RETRY_EXPECTED( |
- epoll_wait(epoll_fd, events, kMaxEvents, -1)); |
- if ((result < 0) && (errno != EWOULDBLOCK)) { |
- return ProcessWaitCleanup(out, err, exit_event, epoll_fd); |
- } |
- for (intptr_t i = 0; i < result; i++) { |
- if ((events[i].events & EPOLLIN) != 0) { |
- const intptr_t avail = FDUtils::AvailableBytes(events[i].data.fd); |
- if (events[i].data.fd == out) { |
- if (!out_data.Read(out, avail)) { |
- return ProcessWaitCleanup(out, err, exit_event, epoll_fd); |
- } |
- } else if (events[i].data.fd == err) { |
- if (!err_data.Read(err, avail)) { |
- return ProcessWaitCleanup(out, err, exit_event, epoll_fd); |
- } |
- } else if (events[i].data.fd == exit_event) { |
- if (avail == 8) { |
- intptr_t b = |
- NO_RETRY_EXPECTED(read(exit_event, exit_code_data.bytes, 8)); |
- if (b != 8) { |
- return ProcessWaitCleanup(out, err, exit_event, epoll_fd); |
- } |
- } |
- } else { |
- UNREACHABLE(); |
+ |
+ for (size_t i = 0; i < 3; ++i) { |
+ entries[i].WaitBegin(&wait_items[i]); |
+ } |
+ mx_object_wait_many(wait_items, 3, MX_TIME_INFINITE); |
+ |
+ for (size_t i = 0; i < 3; ++i) { |
+ entries[i].WaitEnd(&wait_items[i], &events[i]); |
+ } |
+ |
+ if ((events[0] & EPOLLIN) != 0) { |
+ const intptr_t avail = FDUtils::AvailableBytes(out); |
+ if (!out_data.Read(out, avail)) { |
+ return ProcessWaitCleanup(out, err, exit_event); |
+ } |
+ } |
+ if ((events[1] & EPOLLIN) != 0) { |
+ const intptr_t avail = FDUtils::AvailableBytes(err); |
+ if (!err_data.Read(err, avail)) { |
+ return ProcessWaitCleanup(err, err, exit_event); |
+ } |
+ } |
+ if ((events[2] & EPOLLIN) != 0) { |
+ const intptr_t avail = FDUtils::AvailableBytes(exit_event); |
+ if (avail == 8) { |
+ intptr_t b = |
+ NO_RETRY_EXPECTED(read(exit_event, exit_code_data.bytes, 8)); |
+ if (b != 8) { |
+ return ProcessWaitCleanup(out, err, exit_event); |
} |
} |
- if ((events[i].events & (EPOLLHUP | EPOLLRDHUP)) != 0) { |
- NO_RETRY_EXPECTED(close(events[i].data.fd)); |
+ } |
+ for (size_t i = 0; i < 3; ++i) { |
+ if ((events[i] & EPOLLRDHUP) != 0) { |
active--; |
- VOID_NO_RETRY_EXPECTED( |
- epoll_ctl(epoll_fd, EPOLL_CTL_DEL, events[i].data.fd, NULL)); |
+ entries[i].Cancel(); |
} |
} |
} |
- VOID_NO_RETRY_EXPECTED(close(epoll_fd)); |
// All handles closed and all data read. |
result->set_stdout_data(out_data.GetData()); |
@@ -582,7 +585,6 @@ bool Process::Wait(intptr_t pid, |
return true; |
} |
- |
bool Process::Kill(intptr_t id, int signal) { |
LOG_INFO("Sending signal %d to process with id %ld\n", signal, id); |
// mx_task_kill is definitely going to kill the process. |
@@ -609,7 +611,6 @@ bool Process::Kill(intptr_t id, int signal) { |
return true; |
} |
- |
class ProcessStarter { |
public: |
ProcessStarter(const char* path, |
@@ -735,14 +736,14 @@ class ProcessStarter { |
} |
private: |
-#define CHECK_FOR_ERROR(status, msg) \ |
- if (status < 0) { \ |
- const intptr_t kMaxMessageSize = 256; \ |
- char* message = DartUtils::ScopedCString(kMaxMessageSize); \ |
- snprintf(message, kMaxMessageSize, "%s:%d: %s: %s\n", __FILE__, __LINE__, \ |
- msg, mx_status_get_string(status)); \ |
- *os_error_message_ = message; \ |
- return status; \ |
+#define CHECK_FOR_ERROR(status, msg) \ |
zra
2017/05/26 16:13:22
It looks like the escaped newlines were already in
|
+ if (status < 0) { \ |
+ const intptr_t kMaxMessageSize = 256; \ |
+ char* message = DartUtils::ScopedCString(kMaxMessageSize); \ |
+ snprintf(message, kMaxMessageSize, "%s:%d: %s: %s\n", __FILE__, __LINE__, \ |
+ msg, mx_status_get_string(status)); \ |
+ *os_error_message_ = message; \ |
+ return status; \ |
} |
mx_status_t SetupLaunchpad(launchpad_t** launchpad) { |
@@ -802,7 +803,6 @@ class ProcessStarter { |
DISALLOW_IMPLICIT_CONSTRUCTORS(ProcessStarter); |
}; |
- |
int Process::Start(const char* path, |
char* arguments[], |
intptr_t arguments_length, |
@@ -827,15 +827,12 @@ int Process::Start(const char* path, |
return starter.Start(); |
} |
- |
intptr_t Process::SetSignalHandler(intptr_t signal) { |
errno = ENOSYS; |
return -1; |
} |
- |
-void Process::ClearSignalHandler(intptr_t signal) { |
-} |
+void Process::ClearSignalHandler(intptr_t signal) {} |
} // namespace bin |
} // namespace dart |