| OLD | NEW | 
|---|
| 1 // Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file | 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 | 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. | 3 // BSD-style license that can be found in the LICENSE file. | 
| 4 | 4 | 
| 5 #if !defined(DART_IO_DISABLED) | 5 #if !defined(DART_IO_DISABLED) | 
| 6 | 6 | 
| 7 #include "platform/globals.h" | 7 #include "platform/globals.h" | 
| 8 #if defined(TARGET_OS_FUCHSIA) | 8 #if defined(TARGET_OS_FUCHSIA) | 
| 9 | 9 | 
| 10 #include "bin/eventhandler.h" | 10 #include "bin/eventhandler.h" | 
| 11 #include "bin/eventhandler_fuchsia.h" | 11 #include "bin/eventhandler_fuchsia.h" | 
| 12 | 12 | 
| 13 #include <magenta/status.h> | 13 #include <magenta/status.h> | 
| 14 #include <magenta/syscalls.h> | 14 #include <magenta/syscalls.h> | 
| 15 | 15 | 
|  | 16 #include "bin/log.h" | 
| 16 #include "bin/thread.h" | 17 #include "bin/thread.h" | 
| 17 #include "bin/utils.h" | 18 #include "bin/utils.h" | 
| 18 | 19 | 
|  | 20 #if defined(EVENTHANDLER_LOGGING) | 
|  | 21 #define LOG_ERR(msg, ...) Log::PrintErr(msg, ##__VA_ARGS__) | 
|  | 22 #define LOG_INFO(msg, ...) Log::Print(msg, ##__VA_ARGS__) | 
|  | 23 #else | 
|  | 24 #define LOG_ERR(msg, ...) | 
|  | 25 #define LOG_INFO(msg, ...) | 
|  | 26 #endif  // defined(EVENTHANDLER_LOGGING) | 
|  | 27 | 
| 19 namespace dart { | 28 namespace dart { | 
| 20 namespace bin { | 29 namespace bin { | 
| 21 | 30 | 
|  | 31 MagentaWaitManyInfo::MagentaWaitManyInfo() | 
|  | 32     : capacity_(kInitialCapacity), | 
|  | 33       size_(0) { | 
|  | 34   descriptor_infos_ = static_cast<DescriptorInfo**>( | 
|  | 35       malloc(kInitialCapacity * sizeof(*descriptor_infos_))); | 
|  | 36   if (descriptor_infos_ == NULL) { | 
|  | 37     FATAL("Failed to allocate descriptor_infos array"); | 
|  | 38   } | 
|  | 39   handles_ = static_cast<mx_handle_t*>( | 
|  | 40       malloc(kInitialCapacity * sizeof(*handles_))); | 
|  | 41   if (handles_ == NULL) { | 
|  | 42     FATAL("Failed to allocate handles array"); | 
|  | 43   } | 
|  | 44   signals_ = static_cast<mx_signals_t*>( | 
|  | 45       malloc(kInitialCapacity * sizeof(*signals_))); | 
|  | 46   if (signals_ == NULL) { | 
|  | 47     FATAL("Failed to allocate signals array"); | 
|  | 48   } | 
|  | 49   signals_states_ = static_cast<mx_signals_state_t*>( | 
|  | 50       malloc(kInitialCapacity * sizeof(*signals_states_))); | 
|  | 51   if (signals_states_ == NULL) { | 
|  | 52     FATAL("Failed to allocate signals_states array"); | 
|  | 53   } | 
|  | 54 } | 
|  | 55 | 
|  | 56 | 
|  | 57 MagentaWaitManyInfo::~MagentaWaitManyInfo() { | 
|  | 58   free(descriptor_infos_); | 
|  | 59   free(handles_); | 
|  | 60   free(signals_); | 
|  | 61   free(signals_states_); | 
|  | 62 } | 
|  | 63 | 
|  | 64 | 
|  | 65 void MagentaWaitManyInfo::AddHandle(mx_handle_t handle, | 
|  | 66                                     mx_signals_t signals, | 
|  | 67                                     DescriptorInfo* di) { | 
|  | 68 #if defined(DEBUG) | 
|  | 69   // Check that the handle is not already in the list. | 
|  | 70   for (intptr_t i = 0; i < size_; i++) { | 
|  | 71     if (handles_[i] == handle) { | 
|  | 72       FATAL("The handle is already in the list!"); | 
|  | 73     } | 
|  | 74   } | 
|  | 75 #endif | 
|  | 76   intptr_t new_size = size_ + 1; | 
|  | 77   GrowArraysIfNeeded(new_size); | 
|  | 78   descriptor_infos_[size_] = di; | 
|  | 79   handles_[size_] = handle; | 
|  | 80   signals_[size_] = signals; | 
|  | 81   signals_states_[size_].satisfied = MX_SIGNAL_NONE; | 
|  | 82   signals_states_[size_].satisfiable = MX_SIGNAL_NONE; | 
|  | 83   size_ = new_size; | 
|  | 84   LOG_INFO("AddHandle(%ld, %ld, %p), size = %ld\n", handle, signals, di, size_); | 
|  | 85 } | 
|  | 86 | 
|  | 87 | 
|  | 88 void MagentaWaitManyInfo::RemoveHandle(mx_handle_t handle) { | 
|  | 89   intptr_t idx; | 
|  | 90   for (idx = 1; idx < size_; idx++) { | 
|  | 91     if (handle == handles_[idx]) { | 
|  | 92       break; | 
|  | 93     } | 
|  | 94   } | 
|  | 95   if (idx == size_) { | 
|  | 96     FATAL("Handle is not in the list!"); | 
|  | 97   } | 
|  | 98 | 
|  | 99   if (idx != (size_ - 1)) { | 
|  | 100     descriptor_infos_[idx] = descriptor_infos_[size_ - 1]; | 
|  | 101     handles_[idx] = handles_[size_ - 1]; | 
|  | 102     signals_[idx] = signals_[size_ - 1]; | 
|  | 103     signals_states_[idx] = signals_states_[size_ - 1]; | 
|  | 104   } | 
|  | 105   descriptor_infos_[size_ - 1] = NULL; | 
|  | 106   handles_[size_ - 1] = MX_HANDLE_INVALID; | 
|  | 107   signals_[size_ - 1] = MX_SIGNAL_NONE; | 
|  | 108   signals_states_[size_ - 1].satisfied = MX_SIGNAL_NONE; | 
|  | 109   signals_states_[size_ - 1].satisfiable = MX_SIGNAL_NONE; | 
|  | 110   size_ = size_ - 1; | 
|  | 111   LOG_INFO("RemoveHandle(%ld), size = %ld\n", handle, size_); | 
|  | 112 } | 
|  | 113 | 
|  | 114 | 
|  | 115 void MagentaWaitManyInfo::GrowArraysIfNeeded(intptr_t desired_size) { | 
|  | 116   if (desired_size < capacity_) { | 
|  | 117     return; | 
|  | 118   } | 
|  | 119   intptr_t new_capacity = desired_size + (desired_size >> 1); | 
|  | 120   descriptor_infos_ = static_cast<DescriptorInfo**>( | 
|  | 121       realloc(descriptor_infos_, new_capacity * sizeof(*descriptor_infos_))); | 
|  | 122   if (descriptor_infos_ == NULL) { | 
|  | 123     FATAL("Failed to grow descriptor_infos array"); | 
|  | 124   } | 
|  | 125   handles_ = static_cast<mx_handle_t*>( | 
|  | 126       realloc(handles_, new_capacity * sizeof(*handles_))); | 
|  | 127   if (handles_ == NULL) { | 
|  | 128     FATAL("Failed to grow handles array"); | 
|  | 129   } | 
|  | 130   signals_ = static_cast<mx_signals_t*>( | 
|  | 131       realloc(signals_, new_capacity * sizeof(*signals_))); | 
|  | 132   if (signals_ == NULL) { | 
|  | 133     FATAL("Failed to grow signals array"); | 
|  | 134   } | 
|  | 135   signals_states_ = static_cast<mx_signals_state_t*>( | 
|  | 136       realloc(signals_states_, new_capacity * sizeof(*signals_states_))); | 
|  | 137   if (signals_states_ == NULL) { | 
|  | 138     FATAL("Failed to grow signals_states array"); | 
|  | 139   } | 
|  | 140   capacity_ = new_capacity; | 
|  | 141   LOG_INFO("GrowArraysIfNeeded(%ld), capacity = %ld\n", | 
|  | 142            desired_size, capacity_); | 
|  | 143 } | 
|  | 144 | 
|  | 145 | 
| 22 EventHandlerImplementation::EventHandlerImplementation() { | 146 EventHandlerImplementation::EventHandlerImplementation() { | 
| 23   mx_status_t status = mx_msgpipe_create(interrupt_handles_, 0); | 147   mx_status_t status = mx_msgpipe_create(interrupt_handles_, 0); | 
| 24   if (status != NO_ERROR) { | 148   if (status != NO_ERROR) { | 
| 25     FATAL1("mx_msgpipe_create failed: %s\n", mx_status_get_string(status)); | 149     FATAL1("mx_msgpipe_create failed: %s\n", mx_status_get_string(status)); | 
| 26   } | 150   } | 
| 27   shutdown_ = false; | 151   shutdown_ = false; | 
|  | 152   info_.AddHandle(interrupt_handles_[0], | 
|  | 153                   MX_SIGNAL_READABLE | MX_SIGNAL_PEER_CLOSED, | 
|  | 154                   NULL); | 
|  | 155   LOG_INFO("EventHandlerImplementation initialized\n"); | 
| 28 } | 156 } | 
| 29 | 157 | 
| 30 | 158 | 
| 31 EventHandlerImplementation::~EventHandlerImplementation() { | 159 EventHandlerImplementation::~EventHandlerImplementation() { | 
| 32   mx_status_t status = mx_handle_close(interrupt_handles_[0]); | 160   mx_status_t status = mx_handle_close(interrupt_handles_[0]); | 
| 33   if (status != NO_ERROR) { | 161   if (status != NO_ERROR) { | 
| 34     FATAL1("mx_handle_close failed: %s\n", mx_status_get_string(status)); | 162     FATAL1("mx_handle_close failed: %s\n", mx_status_get_string(status)); | 
| 35   } | 163   } | 
| 36   status = mx_handle_close(interrupt_handles_[1]); | 164   status = mx_handle_close(interrupt_handles_[1]); | 
| 37   if (status != NO_ERROR) { | 165   if (status != NO_ERROR) { | 
| 38     FATAL1("mx_handle_close failed: %s\n", mx_status_get_string(status)); | 166     FATAL1("mx_handle_close failed: %s\n", mx_status_get_string(status)); | 
| 39   } | 167   } | 
|  | 168   LOG_INFO("EventHandlerImplementation destroyed\n"); | 
| 40 } | 169 } | 
| 41 | 170 | 
| 42 | 171 | 
| 43 void EventHandlerImplementation::WakeupHandler(intptr_t id, | 172 void EventHandlerImplementation::WakeupHandler(intptr_t id, | 
| 44                                                Dart_Port dart_port, | 173                                                Dart_Port dart_port, | 
| 45                                                int64_t data) { | 174                                                int64_t data) { | 
| 46   InterruptMessage msg; | 175   InterruptMessage msg; | 
| 47   msg.id = id; | 176   msg.id = id; | 
| 48   msg.dart_port = dart_port; | 177   msg.dart_port = dart_port; | 
| 49   msg.data = data; | 178   msg.data = data; | 
| 50 | 179 | 
| 51   mx_status_t status = | 180   mx_status_t status = | 
| 52     mx_msgpipe_write(interrupt_handles_[1], &msg, sizeof(msg), NULL, 0, 0); | 181     mx_msgpipe_write(interrupt_handles_[1], &msg, sizeof(msg), NULL, 0, 0); | 
| 53   if (status != NO_ERROR) { | 182   if (status != NO_ERROR) { | 
| 54     FATAL1("mx_msgpipe_write failed: %s\n", mx_status_get_string(status)); | 183     FATAL1("mx_msgpipe_write failed: %s\n", mx_status_get_string(status)); | 
| 55   } | 184   } | 
|  | 185   LOG_INFO("WakeupHandler(%ld, %ld, %lld)\n", id, dart_port, data); | 
| 56 } | 186 } | 
| 57 | 187 | 
| 58 | 188 | 
| 59 void EventHandlerImplementation::HandleInterruptFd() { | 189 void EventHandlerImplementation::HandleInterruptFd() { | 
|  | 190   LOG_INFO("HandleInterruptFd entry\n"); | 
| 60   InterruptMessage msg; | 191   InterruptMessage msg; | 
| 61   uint32_t bytes = kInterruptMessageSize; | 192   uint32_t bytes = kInterruptMessageSize; | 
| 62   mx_status_t status; | 193   mx_status_t status; | 
| 63   while (true) { | 194   while (true) { | 
| 64     status = mx_msgpipe_read( | 195     status = mx_msgpipe_read( | 
| 65         interrupt_handles_[0], &msg, &bytes, NULL, NULL, 0); | 196         interrupt_handles_[0], &msg, &bytes, NULL, NULL, 0); | 
| 66     if (status != NO_ERROR) { | 197     if (status != NO_ERROR) { | 
| 67       break; | 198       break; | 
| 68     } | 199     } | 
| 69     ASSERT(bytes == kInterruptMessageSize); | 200     ASSERT(bytes == kInterruptMessageSize); | 
| 70     if (msg.id == kTimerId) { | 201     if (msg.id == kTimerId) { | 
|  | 202       LOG_INFO("HandleInterruptFd read timer update\n"); | 
| 71       timeout_queue_.UpdateTimeout(msg.dart_port, msg.data); | 203       timeout_queue_.UpdateTimeout(msg.dart_port, msg.data); | 
| 72     } else if (msg.id == kShutdownId) { | 204     } else if (msg.id == kShutdownId) { | 
|  | 205       LOG_INFO("HandleInterruptFd read shutdown\n"); | 
| 73       shutdown_ = true; | 206       shutdown_ = true; | 
| 74     } else { | 207     } else { | 
|  | 208       // TODO(zra): Handle commands to add and remove handles from the | 
|  | 209       // MagentaWaitManyInfo. | 
| 75       UNIMPLEMENTED(); | 210       UNIMPLEMENTED(); | 
| 76     } | 211     } | 
| 77   } | 212   } | 
| 78   // status == ERR_SHOULD_WAIT when we try to read and there are no messages | 213   // status == ERR_SHOULD_WAIT when we try to read and there are no messages | 
| 79   // available, so it is an error if we get here and status != ERR_SHOULD_WAIT. | 214   // available, so it is an error if we get here and status != ERR_SHOULD_WAIT. | 
| 80   if (status != ERR_SHOULD_WAIT) { | 215   if (status != ERR_SHOULD_WAIT) { | 
| 81     FATAL1("mx_msgpipe_read failed: %s\n", mx_status_get_string(status)); | 216     FATAL1("mx_msgpipe_read failed: %s\n", mx_status_get_string(status)); | 
| 82   } | 217   } | 
|  | 218   LOG_INFO("HandleInterruptFd exit\n"); | 
|  | 219 } | 
|  | 220 | 
|  | 221 | 
|  | 222 void EventHandlerImplementation::HandleEvents() { | 
|  | 223   LOG_INFO("HandleEvents entry\n"); | 
|  | 224   for (intptr_t i = 1; i < info_.size(); i++) { | 
|  | 225     if (info_.signals_states()[i].satisfied != MX_SIGNAL_NONE) { | 
|  | 226       // Only the control handle has no descriptor info. | 
|  | 227       ASSERT(info_.descriptor_infos()[i] != NULL); | 
|  | 228       ASSERT(info_.handles()[i] != interrupt_handles_[0]); | 
|  | 229       // TODO(zra): Handle events on other handles. At the moment we are | 
|  | 230       // only interrupted when there is a message on interrupt_handles_[0]. | 
|  | 231       UNIMPLEMENTED(); | 
|  | 232     } | 
|  | 233   } | 
|  | 234 | 
|  | 235   if ((info_.signals_states()[0].satisfied & MX_SIGNAL_PEER_CLOSED) != 0) { | 
|  | 236     FATAL("EventHandlerImplementation::Poll: Unexpected peer closed\n"); | 
|  | 237   } | 
|  | 238   if ((info_.signals_states()[0].satisfied & MX_SIGNAL_READABLE) != 0) { | 
|  | 239     LOG_INFO("HandleEvents interrupt_handles_[0] readable\n"); | 
|  | 240     HandleInterruptFd(); | 
|  | 241   } else { | 
|  | 242     LOG_INFO("HandleEvents interrupt_handles_[0] not readable\n"); | 
|  | 243   } | 
| 83 } | 244 } | 
| 84 | 245 | 
| 85 | 246 | 
| 86 void EventHandlerImplementation::HandleEvents() { |  | 
| 87   // TODO(zra): Handle events from other handles. At the moment we are only |  | 
| 88   // interrupted when there is a message on interrupt_handles_[0]. |  | 
| 89   HandleInterruptFd(); |  | 
| 90 } |  | 
| 91 |  | 
| 92 |  | 
| 93 int64_t EventHandlerImplementation::GetTimeout() const { | 247 int64_t EventHandlerImplementation::GetTimeout() const { | 
| 94   if (!timeout_queue_.HasTimeout()) { | 248   if (!timeout_queue_.HasTimeout()) { | 
| 95     return kInfinityTimeout; | 249     return kInfinityTimeout; | 
| 96   } | 250   } | 
| 97   int64_t millis = timeout_queue_.CurrentTimeout() - | 251   int64_t millis = timeout_queue_.CurrentTimeout() - | 
| 98       TimerUtils::GetCurrentMonotonicMillis(); | 252       TimerUtils::GetCurrentMonotonicMillis(); | 
| 99   return (millis < 0) ? 0 : millis; | 253   return (millis < 0) ? 0 : millis; | 
| 100 } | 254 } | 
| 101 | 255 | 
| 102 | 256 | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
| 113 | 267 | 
| 114 | 268 | 
| 115 void EventHandlerImplementation::Poll(uword args) { | 269 void EventHandlerImplementation::Poll(uword args) { | 
| 116   EventHandler* handler = reinterpret_cast<EventHandler*>(args); | 270   EventHandler* handler = reinterpret_cast<EventHandler*>(args); | 
| 117   EventHandlerImplementation* handler_impl = &handler->delegate_; | 271   EventHandlerImplementation* handler_impl = &handler->delegate_; | 
| 118   ASSERT(handler_impl != NULL); | 272   ASSERT(handler_impl != NULL); | 
| 119 | 273 | 
| 120   while (!handler_impl->shutdown_) { | 274   while (!handler_impl->shutdown_) { | 
| 121     int64_t millis = handler_impl->GetTimeout(); | 275     int64_t millis = handler_impl->GetTimeout(); | 
| 122     ASSERT((millis == kInfinityTimeout) || (millis >= 0)); | 276     ASSERT((millis == kInfinityTimeout) || (millis >= 0)); | 
| 123 |  | 
| 124     mx_time_t timeout = | 277     mx_time_t timeout = | 
| 125         millis * kMicrosecondsPerMillisecond * kNanosecondsPerMicrosecond; | 278         millis * kMicrosecondsPerMillisecond * kNanosecondsPerMicrosecond; | 
| 126     mx_signals_state_t signals_state; | 279     const MagentaWaitManyInfo& info = handler_impl->info(); | 
| 127     mx_status_t status = mx_handle_wait_one( | 280     uint32_t result_index; | 
| 128         handler_impl->interrupt_handles_[0], | 281     LOG_INFO("mx_handle_wait_many(%ld, %p, %p, %lld, %p, %p)\n", | 
| 129         MX_SIGNAL_READABLE | MX_SIGNAL_PEER_CLOSED, | 282         info.size(), info.handles(), info.signals(), timeout, &result_index, | 
|  | 283         info.signals_states()); | 
|  | 284     mx_status_t status = mx_handle_wait_many( | 
|  | 285         info.size(), | 
|  | 286         info.handles(), | 
|  | 287         info.signals(), | 
| 130         timeout, | 288         timeout, | 
| 131         &signals_state); | 289         &result_index, | 
|  | 290         info.signals_states()); | 
| 132     if ((status != NO_ERROR) && (status != ERR_TIMED_OUT)) { | 291     if ((status != NO_ERROR) && (status != ERR_TIMED_OUT)) { | 
| 133       FATAL1("mx_handle_wait_one failed: %s\n", mx_status_get_string(status)); | 292       FATAL1("mx_handle_wait_many failed: %s\n", mx_status_get_string(status)); | 
| 134     } else { | 293     } else { | 
|  | 294       LOG_INFO("mx_handle_wait_many returned: %ld\n", status); | 
| 135       handler_impl->HandleTimeout(); | 295       handler_impl->HandleTimeout(); | 
| 136       if ((signals_state.satisfied & MX_SIGNAL_READABLE) != 0) { | 296       handler_impl->HandleEvents(); | 
| 137         handler_impl->HandleEvents(); |  | 
| 138       } |  | 
| 139       if ((signals_state.satisfied & MX_SIGNAL_PEER_CLOSED) != 0) { |  | 
| 140         FATAL("EventHandlerImplementation::Poll: Unexpected peer closed\n"); |  | 
| 141       } |  | 
| 142     } | 297     } | 
| 143   } | 298   } | 
| 144   handler->NotifyShutdownDone(); | 299   handler->NotifyShutdownDone(); | 
|  | 300   LOG_INFO("EventHandlerImplementation notifying about shutdown\n"); | 
| 145 } | 301 } | 
| 146 | 302 | 
| 147 | 303 | 
| 148 void EventHandlerImplementation::Start(EventHandler* handler) { | 304 void EventHandlerImplementation::Start(EventHandler* handler) { | 
| 149   int result = Thread::Start(&EventHandlerImplementation::Poll, | 305   int result = Thread::Start(&EventHandlerImplementation::Poll, | 
| 150                              reinterpret_cast<uword>(handler)); | 306                              reinterpret_cast<uword>(handler)); | 
| 151   if (result != 0) { | 307   if (result != 0) { | 
| 152     FATAL1("Failed to start event handler thread %d", result); | 308     FATAL1("Failed to start event handler thread %d", result); | 
| 153   } | 309   } | 
| 154 } | 310 } | 
| 155 | 311 | 
| 156 | 312 | 
| 157 void EventHandlerImplementation::Shutdown() { | 313 void EventHandlerImplementation::Shutdown() { | 
| 158   SendData(kShutdownId, 0, 0); | 314   SendData(kShutdownId, 0, 0); | 
| 159 } | 315 } | 
| 160 | 316 | 
| 161 | 317 | 
| 162 void EventHandlerImplementation::SendData(intptr_t id, | 318 void EventHandlerImplementation::SendData(intptr_t id, | 
| 163                                           Dart_Port dart_port, | 319                                           Dart_Port dart_port, | 
| 164                                           int64_t data) { | 320                                           int64_t data) { | 
| 165   WakeupHandler(id, dart_port, data); | 321   WakeupHandler(id, dart_port, data); | 
| 166 } | 322 } | 
| 167 | 323 | 
| 168 }  // namespace bin | 324 }  // namespace bin | 
| 169 }  // namespace dart | 325 }  // namespace dart | 
| 170 | 326 | 
| 171 #endif  // defined(TARGET_OS_FUCHSIA) | 327 #endif  // defined(TARGET_OS_FUCHSIA) | 
| 172 | 328 | 
| 173 #endif  // !defined(DART_IO_DISABLED) | 329 #endif  // !defined(DART_IO_DISABLED) | 
| OLD | NEW | 
|---|