Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | |
| 2 // for details. All rights reserved. Use of this source code is governed by a | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 #if !defined(DART_IO_DISABLED) | |
| 6 | |
| 7 #include "platform/globals.h" | |
| 8 #if defined(TARGET_OS_FUCHSIA) | |
| 9 | |
| 10 #include "bin/eventhandler.h" | |
| 11 #include "bin/eventhandler_fuchsia.h" | |
| 12 | |
| 13 #include <magenta/syscalls.h> | |
| 14 #include <runtime/status.h> | |
| 15 | |
| 16 #include "bin/thread.h" | |
| 17 #include "bin/utils.h" | |
| 18 | |
| 19 namespace dart { | |
| 20 namespace bin { | |
| 21 | |
| 22 EventHandlerImplementation::EventHandlerImplementation() { | |
| 23 mx_status_t status = mx_message_pipe_create(interrupt_handles_, 0); | |
| 24 if (status != NO_ERROR) { | |
| 25 FATAL1("mx_message_pipe_create failed: %s\n", mx_strstatus(status)); | |
| 26 } | |
| 27 } | |
| 28 | |
| 29 | |
| 30 EventHandlerImplementation::~EventHandlerImplementation() { | |
| 31 mx_status_t status = mx_handle_close(interrupt_handles_[0]); | |
| 32 if (status != NO_ERROR) { | |
| 33 FATAL1("mx_handle_close failed: %s\n", mx_strstatus(status)); | |
| 34 } | |
| 35 status = mx_handle_close(interrupt_handles_[1]); | |
| 36 if (status != NO_ERROR) { | |
| 37 FATAL1("mx_handle_close failed: %s\n", mx_strstatus(status)); | |
| 38 } | |
| 39 } | |
| 40 | |
| 41 | |
| 42 void EventHandlerImplementation::WakeupHandler(intptr_t id, | |
| 43 Dart_Port dart_port, | |
| 44 int64_t data) { | |
| 45 InterruptMessage msg; | |
| 46 msg.id = id; | |
| 47 msg.dart_port = dart_port; | |
| 48 msg.data = data; | |
| 49 | |
| 50 mx_status_t status = | |
| 51 mx_message_write(interrupt_handles_[1], &msg, sizeof(msg), NULL, 0, 0); | |
| 52 if (status != NO_ERROR) { | |
| 53 FATAL1("mx_message_write failed: %s\n", mx_strstatus(status)); | |
| 54 } | |
| 55 } | |
| 56 | |
| 57 | |
| 58 void EventHandlerImplementation::HandleInterruptFd() { | |
| 59 InterruptMessage msg; | |
| 60 uint32_t bytes = kInterruptMessageSize; | |
| 61 mx_status_t status; | |
| 62 while (true) { | |
| 63 status = mx_message_read( | |
| 64 interrupt_handles_[0], &msg, &bytes, NULL, NULL, 0); | |
| 65 if (status != NO_ERROR) { | |
| 66 break; | |
| 67 } | |
| 68 ASSERT(bytes == kInterruptMessageSize); | |
| 69 if (msg.id == kTimerId) { | |
| 70 timeout_queue_.UpdateTimeout(msg.dart_port, msg.data); | |
| 71 } else if (msg.id == kShutdownId) { | |
| 72 shutdown_ = true; | |
| 73 } else { | |
| 74 UNIMPLEMENTED(); | |
| 75 } | |
| 76 } | |
| 77 if (status != ERR_BAD_STATE) { | |
| 78 FATAL1("mx_message_read failed: %s\n", mx_strstatus(status)); | |
| 79 } | |
|
siva
2016/07/22 19:18:22
for status == ERR_BAD_STATE we seem to do nothing,
zra
2016/07/22 20:07:08
status should be ERR_BAD_STATE when we try to read
| |
| 80 } | |
| 81 | |
| 82 | |
| 83 void EventHandlerImplementation::HandleEvents() { | |
| 84 // TODO(zra): Handle events from other handles. At the moment we are only | |
| 85 // interrupted when there is a message on interrupt_handles_[0]. | |
| 86 HandleInterruptFd(); | |
| 87 } | |
| 88 | |
| 89 | |
| 90 int64_t EventHandlerImplementation::GetTimeout() { | |
| 91 if (!timeout_queue_.HasTimeout()) { | |
| 92 return kInfinityTimeout; | |
| 93 } | |
| 94 int64_t millis = timeout_queue_.CurrentTimeout() - | |
| 95 TimerUtils::GetCurrentMonotonicMillis(); | |
| 96 return (millis < 0) ? 0 : millis; | |
| 97 } | |
| 98 | |
| 99 | |
| 100 void EventHandlerImplementation::HandleTimeout() { | |
| 101 if (timeout_queue_.HasTimeout()) { | |
| 102 int64_t millis = timeout_queue_.CurrentTimeout() - | |
| 103 TimerUtils::GetCurrentMonotonicMillis(); | |
| 104 if (millis <= 0) { | |
| 105 DartUtils::PostNull(timeout_queue_.CurrentPort()); | |
| 106 timeout_queue_.RemoveCurrent(); | |
| 107 } | |
| 108 } | |
| 109 } | |
| 110 | |
| 111 | |
| 112 void EventHandlerImplementation::Poll(uword args) { | |
| 113 EventHandler* handler = reinterpret_cast<EventHandler*>(args); | |
| 114 EventHandlerImplementation* handler_impl = &handler->delegate_; | |
| 115 ASSERT(handler_impl != NULL); | |
| 116 | |
| 117 while (!handler_impl->shutdown_) { | |
| 118 int64_t millis = handler_impl->GetTimeout(); | |
| 119 ASSERT((millis == kInfinityTimeout) || (millis >= 0)); | |
| 120 | |
| 121 mx_time_t timeout = | |
| 122 millis * kMicrosecondsPerMillisecond * kNanosecondsPerMicrosecond; | |
| 123 mx_signals_state_t signals_state; | |
| 124 mx_status_t status = mx_handle_wait_one( | |
| 125 handler_impl->interrupt_handles_[0], | |
| 126 MX_SIGNAL_READABLE | MX_SIGNAL_PEER_CLOSED, | |
| 127 timeout, | |
| 128 &signals_state); | |
| 129 if ((status != NO_ERROR) && (status != ERR_TIMED_OUT)) { | |
| 130 FATAL1("mx_handle_wait_one failed: %s\n", mx_strstatus(status)); | |
| 131 } else { | |
| 132 handler_impl->HandleTimeout(); | |
| 133 if ((signals_state.satisfied & MX_SIGNAL_READABLE) != 0) { | |
| 134 handler_impl->HandleEvents(); | |
| 135 } | |
| 136 if ((signals_state.satisfied & MX_SIGNAL_PEER_CLOSED) != 0) { | |
| 137 FATAL("EventHandlerImplementation::Poll: Unexpected peer closed\n"); | |
| 138 } | |
| 139 } | |
| 140 } | |
| 141 handler->NotifyShutdownDone(); | |
| 142 } | |
| 143 | |
| 144 | |
| 145 void EventHandlerImplementation::Start(EventHandler* handler) { | |
| 146 int result = Thread::Start(&EventHandlerImplementation::Poll, | |
| 147 reinterpret_cast<uword>(handler)); | |
| 148 if (result != 0) { | |
| 149 FATAL1("Failed to start event handler thread %d", result); | |
| 150 } | |
| 151 } | |
| 152 | |
| 153 | |
| 154 void EventHandlerImplementation::Shutdown() { | |
| 155 SendData(kShutdownId, 0, 0); | |
| 156 } | |
| 157 | |
| 158 | |
| 159 void EventHandlerImplementation::SendData(intptr_t id, | |
| 160 Dart_Port dart_port, | |
| 161 int64_t data) { | |
| 162 WakeupHandler(id, dart_port, data); | |
| 163 } | |
| 164 | |
| 165 } // namespace bin | |
| 166 } // namespace dart | |
| 167 | |
| 168 #endif // defined(TARGET_OS_FUCHSIA) | |
| 169 | |
| 170 #endif // !defined(DART_IO_DISABLED) | |
| OLD | NEW |