| 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   // status == ERR_BAD_STATE when we try to read and there are no messages | 
|  | 78   // available, so it is an error if we get here and status != ERR_BAD_STATE. | 
|  | 79   if (status != ERR_BAD_STATE) { | 
|  | 80     FATAL1("mx_message_read failed: %s\n", mx_strstatus(status)); | 
|  | 81   } | 
|  | 82 } | 
|  | 83 | 
|  | 84 | 
|  | 85 void EventHandlerImplementation::HandleEvents() { | 
|  | 86   // TODO(zra): Handle events from other handles. At the moment we are only | 
|  | 87   // interrupted when there is a message on interrupt_handles_[0]. | 
|  | 88   HandleInterruptFd(); | 
|  | 89 } | 
|  | 90 | 
|  | 91 | 
|  | 92 int64_t EventHandlerImplementation::GetTimeout() const { | 
|  | 93   if (!timeout_queue_.HasTimeout()) { | 
|  | 94     return kInfinityTimeout; | 
|  | 95   } | 
|  | 96   int64_t millis = timeout_queue_.CurrentTimeout() - | 
|  | 97       TimerUtils::GetCurrentMonotonicMillis(); | 
|  | 98   return (millis < 0) ? 0 : millis; | 
|  | 99 } | 
|  | 100 | 
|  | 101 | 
|  | 102 void EventHandlerImplementation::HandleTimeout() { | 
|  | 103   if (timeout_queue_.HasTimeout()) { | 
|  | 104     int64_t millis = timeout_queue_.CurrentTimeout() - | 
|  | 105         TimerUtils::GetCurrentMonotonicMillis(); | 
|  | 106     if (millis <= 0) { | 
|  | 107       DartUtils::PostNull(timeout_queue_.CurrentPort()); | 
|  | 108       timeout_queue_.RemoveCurrent(); | 
|  | 109     } | 
|  | 110   } | 
|  | 111 } | 
|  | 112 | 
|  | 113 | 
|  | 114 void EventHandlerImplementation::Poll(uword args) { | 
|  | 115   EventHandler* handler = reinterpret_cast<EventHandler*>(args); | 
|  | 116   EventHandlerImplementation* handler_impl = &handler->delegate_; | 
|  | 117   ASSERT(handler_impl != NULL); | 
|  | 118 | 
|  | 119   while (!handler_impl->shutdown_) { | 
|  | 120     int64_t millis = handler_impl->GetTimeout(); | 
|  | 121     ASSERT((millis == kInfinityTimeout) || (millis >= 0)); | 
|  | 122 | 
|  | 123     mx_time_t timeout = | 
|  | 124         millis * kMicrosecondsPerMillisecond * kNanosecondsPerMicrosecond; | 
|  | 125     mx_signals_state_t signals_state; | 
|  | 126     mx_status_t status = mx_handle_wait_one( | 
|  | 127         handler_impl->interrupt_handles_[0], | 
|  | 128         MX_SIGNAL_READABLE | MX_SIGNAL_PEER_CLOSED, | 
|  | 129         timeout, | 
|  | 130         &signals_state); | 
|  | 131     if ((status != NO_ERROR) && (status != ERR_TIMED_OUT)) { | 
|  | 132       FATAL1("mx_handle_wait_one failed: %s\n", mx_strstatus(status)); | 
|  | 133     } else { | 
|  | 134       handler_impl->HandleTimeout(); | 
|  | 135       if ((signals_state.satisfied & MX_SIGNAL_READABLE) != 0) { | 
|  | 136         handler_impl->HandleEvents(); | 
|  | 137       } | 
|  | 138       if ((signals_state.satisfied & MX_SIGNAL_PEER_CLOSED) != 0) { | 
|  | 139         FATAL("EventHandlerImplementation::Poll: Unexpected peer closed\n"); | 
|  | 140       } | 
|  | 141     } | 
|  | 142   } | 
|  | 143   handler->NotifyShutdownDone(); | 
|  | 144 } | 
|  | 145 | 
|  | 146 | 
|  | 147 void EventHandlerImplementation::Start(EventHandler* handler) { | 
|  | 148   int result = Thread::Start(&EventHandlerImplementation::Poll, | 
|  | 149                              reinterpret_cast<uword>(handler)); | 
|  | 150   if (result != 0) { | 
|  | 151     FATAL1("Failed to start event handler thread %d", result); | 
|  | 152   } | 
|  | 153 } | 
|  | 154 | 
|  | 155 | 
|  | 156 void EventHandlerImplementation::Shutdown() { | 
|  | 157   SendData(kShutdownId, 0, 0); | 
|  | 158 } | 
|  | 159 | 
|  | 160 | 
|  | 161 void EventHandlerImplementation::SendData(intptr_t id, | 
|  | 162                                           Dart_Port dart_port, | 
|  | 163                                           int64_t data) { | 
|  | 164   WakeupHandler(id, dart_port, data); | 
|  | 165 } | 
|  | 166 | 
|  | 167 }  // namespace bin | 
|  | 168 }  // namespace dart | 
|  | 169 | 
|  | 170 #endif  // defined(TARGET_OS_FUCHSIA) | 
|  | 171 | 
|  | 172 #endif  // !defined(DART_IO_DISABLED) | 
| OLD | NEW | 
|---|