| 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" |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 namespace bin { | 29 namespace bin { |
| 30 | 30 |
| 31 MagentaWaitManyInfo::MagentaWaitManyInfo() | 31 MagentaWaitManyInfo::MagentaWaitManyInfo() |
| 32 : capacity_(kInitialCapacity), | 32 : capacity_(kInitialCapacity), |
| 33 size_(0) { | 33 size_(0) { |
| 34 descriptor_infos_ = static_cast<DescriptorInfo**>( | 34 descriptor_infos_ = static_cast<DescriptorInfo**>( |
| 35 malloc(kInitialCapacity * sizeof(*descriptor_infos_))); | 35 malloc(kInitialCapacity * sizeof(*descriptor_infos_))); |
| 36 if (descriptor_infos_ == NULL) { | 36 if (descriptor_infos_ == NULL) { |
| 37 FATAL("Failed to allocate descriptor_infos array"); | 37 FATAL("Failed to allocate descriptor_infos array"); |
| 38 } | 38 } |
| 39 handles_ = static_cast<mx_handle_t*>( | 39 items_ = static_cast<mx_wait_item_t*>( |
| 40 malloc(kInitialCapacity * sizeof(*handles_))); | 40 malloc(kInitialCapacity * sizeof(*items_))); |
| 41 if (handles_ == NULL) { | 41 if (items_ == NULL) { |
| 42 FATAL("Failed to allocate handles array"); | 42 FATAL("Failed to allocate items 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 } | 43 } |
| 54 } | 44 } |
| 55 | 45 |
| 56 | 46 |
| 57 MagentaWaitManyInfo::~MagentaWaitManyInfo() { | 47 MagentaWaitManyInfo::~MagentaWaitManyInfo() { |
| 58 free(descriptor_infos_); | 48 free(descriptor_infos_); |
| 59 free(handles_); | 49 free(items_); |
| 60 free(signals_); | |
| 61 free(signals_states_); | |
| 62 } | 50 } |
| 63 | 51 |
| 64 | 52 |
| 65 void MagentaWaitManyInfo::AddHandle(mx_handle_t handle, | 53 void MagentaWaitManyInfo::AddHandle(mx_handle_t handle, |
| 66 mx_signals_t signals, | 54 mx_signals_t signals, |
| 67 DescriptorInfo* di) { | 55 DescriptorInfo* di) { |
| 68 #if defined(DEBUG) | 56 #if defined(DEBUG) |
| 69 // Check that the handle is not already in the list. | 57 // Check that the handle is not already in the list. |
| 70 for (intptr_t i = 0; i < size_; i++) { | 58 for (intptr_t i = 0; i < size_; i++) { |
| 71 if (handles_[i] == handle) { | 59 if (items_[i].handle == handle) { |
| 72 FATAL("The handle is already in the list!"); | 60 FATAL("The handle is already in the list!"); |
| 73 } | 61 } |
| 74 } | 62 } |
| 75 #endif | 63 #endif |
| 76 intptr_t new_size = size_ + 1; | 64 intptr_t new_size = size_ + 1; |
| 77 GrowArraysIfNeeded(new_size); | 65 GrowArraysIfNeeded(new_size); |
| 78 descriptor_infos_[size_] = di; | 66 descriptor_infos_[size_] = di; |
| 79 handles_[size_] = handle; | 67 items_[size_].handle = handle; |
| 80 signals_[size_] = signals; | 68 items_[size_].waitfor = signals; |
| 81 signals_states_[size_].satisfied = MX_SIGNAL_NONE; | 69 items_[size_].pending = 0; |
| 82 signals_states_[size_].satisfiable = MX_SIGNAL_NONE; | |
| 83 size_ = new_size; | 70 size_ = new_size; |
| 84 LOG_INFO("AddHandle(%ld, %ld, %p), size = %ld\n", handle, signals, di, size_); | 71 LOG_INFO("AddHandle(%ld, %ld, %p), size = %ld\n", handle, signals, di, size_); |
| 85 } | 72 } |
| 86 | 73 |
| 87 | 74 |
| 88 void MagentaWaitManyInfo::RemoveHandle(mx_handle_t handle) { | 75 void MagentaWaitManyInfo::RemoveHandle(mx_handle_t handle) { |
| 89 intptr_t idx; | 76 intptr_t idx; |
| 90 for (idx = 1; idx < size_; idx++) { | 77 for (idx = 1; idx < size_; idx++) { |
| 91 if (handle == handles_[idx]) { | 78 if (handle == items_[idx].handle) { |
| 92 break; | 79 break; |
| 93 } | 80 } |
| 94 } | 81 } |
| 95 if (idx == size_) { | 82 if (idx == size_) { |
| 96 FATAL("Handle is not in the list!"); | 83 FATAL("Handle is not in the list!"); |
| 97 } | 84 } |
| 98 | 85 |
| 99 if (idx != (size_ - 1)) { | 86 if (idx != (size_ - 1)) { |
| 100 descriptor_infos_[idx] = descriptor_infos_[size_ - 1]; | 87 descriptor_infos_[idx] = descriptor_infos_[size_ - 1]; |
| 101 handles_[idx] = handles_[size_ - 1]; | 88 items_[idx] = items_[size_ - 1]; |
| 102 signals_[idx] = signals_[size_ - 1]; | |
| 103 signals_states_[idx] = signals_states_[size_ - 1]; | |
| 104 } | 89 } |
| 105 descriptor_infos_[size_ - 1] = NULL; | 90 descriptor_infos_[size_ - 1] = NULL; |
| 106 handles_[size_ - 1] = MX_HANDLE_INVALID; | 91 items_[size_ - 1] = {MX_HANDLE_INVALID, 0, 0}; |
| 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; | 92 size_ = size_ - 1; |
| 111 LOG_INFO("RemoveHandle(%ld), size = %ld\n", handle, size_); | 93 LOG_INFO("RemoveHandle(%ld), size = %ld\n", handle, size_); |
| 112 } | 94 } |
| 113 | 95 |
| 114 | 96 |
| 115 void MagentaWaitManyInfo::GrowArraysIfNeeded(intptr_t desired_size) { | 97 void MagentaWaitManyInfo::GrowArraysIfNeeded(intptr_t desired_size) { |
| 116 if (desired_size < capacity_) { | 98 if (desired_size < capacity_) { |
| 117 return; | 99 return; |
| 118 } | 100 } |
| 119 intptr_t new_capacity = desired_size + (desired_size >> 1); | 101 intptr_t new_capacity = desired_size + (desired_size >> 1); |
| 120 descriptor_infos_ = static_cast<DescriptorInfo**>( | 102 descriptor_infos_ = static_cast<DescriptorInfo**>( |
| 121 realloc(descriptor_infos_, new_capacity * sizeof(*descriptor_infos_))); | 103 realloc(descriptor_infos_, new_capacity * sizeof(*descriptor_infos_))); |
| 122 if (descriptor_infos_ == NULL) { | 104 if (descriptor_infos_ == NULL) { |
| 123 FATAL("Failed to grow descriptor_infos array"); | 105 FATAL("Failed to grow descriptor_infos array"); |
| 124 } | 106 } |
| 125 handles_ = static_cast<mx_handle_t*>( | 107 items_ = static_cast<mx_wait_item_t*>( |
| 126 realloc(handles_, new_capacity * sizeof(*handles_))); | 108 realloc(items_, new_capacity * sizeof(*items_))); |
| 127 if (handles_ == NULL) { | 109 if (items_ == NULL) { |
| 128 FATAL("Failed to grow handles array"); | 110 FATAL("Failed to grow items 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 } | 111 } |
| 140 capacity_ = new_capacity; | 112 capacity_ = new_capacity; |
| 141 LOG_INFO("GrowArraysIfNeeded(%ld), capacity = %ld\n", | 113 LOG_INFO("GrowArraysIfNeeded(%ld), capacity = %ld\n", |
| 142 desired_size, capacity_); | 114 desired_size, capacity_); |
| 143 } | 115 } |
| 144 | 116 |
| 145 | 117 |
| 146 EventHandlerImplementation::EventHandlerImplementation() { | 118 EventHandlerImplementation::EventHandlerImplementation() { |
| 147 mx_status_t status = mx_channel_create(0, &interrupt_handles_[0], | 119 mx_status_t status = mx_channel_create(0, &interrupt_handles_[0], |
| 148 &interrupt_handles_[1]); | 120 &interrupt_handles_[1]); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 216 if (status != ERR_SHOULD_WAIT) { | 188 if (status != ERR_SHOULD_WAIT) { |
| 217 FATAL1("mx_channel_read failed: %s\n", mx_status_get_string(status)); | 189 FATAL1("mx_channel_read failed: %s\n", mx_status_get_string(status)); |
| 218 } | 190 } |
| 219 LOG_INFO("HandleInterruptFd exit\n"); | 191 LOG_INFO("HandleInterruptFd exit\n"); |
| 220 } | 192 } |
| 221 | 193 |
| 222 | 194 |
| 223 void EventHandlerImplementation::HandleEvents() { | 195 void EventHandlerImplementation::HandleEvents() { |
| 224 LOG_INFO("HandleEvents entry\n"); | 196 LOG_INFO("HandleEvents entry\n"); |
| 225 for (intptr_t i = 1; i < info_.size(); i++) { | 197 for (intptr_t i = 1; i < info_.size(); i++) { |
| 226 if (info_.signals_states()[i].satisfied != MX_SIGNAL_NONE) { | 198 const mx_wait_item_t& wait_item = info_.items()[i]; |
| 199 if (wait_item.pending & wait_item.waitfor) { |
| 227 // Only the control handle has no descriptor info. | 200 // Only the control handle has no descriptor info. |
| 228 ASSERT(info_.descriptor_infos()[i] != NULL); | 201 ASSERT(info_.descriptor_infos()[i] != NULL); |
| 229 ASSERT(info_.handles()[i] != interrupt_handles_[0]); | 202 ASSERT(info_.handles()[i] != interrupt_handles_[0]); |
| 230 // TODO(zra): Handle events on other handles. At the moment we are | 203 // TODO(zra): Handle events on other handles. At the moment we are |
| 231 // only interrupted when there is a message on interrupt_handles_[0]. | 204 // only interrupted when there is a message on interrupt_handles_[0]. |
| 232 UNIMPLEMENTED(); | 205 UNIMPLEMENTED(); |
| 233 } | 206 } |
| 234 } | 207 } |
| 235 | 208 |
| 236 if ((info_.signals_states()[0].satisfied & MX_SIGNAL_PEER_CLOSED) != 0) { | 209 if ((info_.items()[0].pending & MX_SIGNAL_PEER_CLOSED) != 0) { |
| 237 FATAL("EventHandlerImplementation::Poll: Unexpected peer closed\n"); | 210 FATAL("EventHandlerImplementation::Poll: Unexpected peer closed\n"); |
| 238 } | 211 } |
| 239 if ((info_.signals_states()[0].satisfied & MX_SIGNAL_READABLE) != 0) { | 212 if ((info_.items()[0].pending & MX_SIGNAL_READABLE) != 0) { |
| 240 LOG_INFO("HandleEvents interrupt_handles_[0] readable\n"); | 213 LOG_INFO("HandleEvents interrupt_handles_[0] readable\n"); |
| 241 HandleInterruptFd(); | 214 HandleInterruptFd(); |
| 242 } else { | 215 } else { |
| 243 LOG_INFO("HandleEvents interrupt_handles_[0] not readable\n"); | 216 LOG_INFO("HandleEvents interrupt_handles_[0] not readable\n"); |
| 244 } | 217 } |
| 245 } | 218 } |
| 246 | 219 |
| 247 | 220 |
| 248 int64_t EventHandlerImplementation::GetTimeout() const { | 221 int64_t EventHandlerImplementation::GetTimeout() const { |
| 249 if (!timeout_queue_.HasTimeout()) { | 222 if (!timeout_queue_.HasTimeout()) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 271 EventHandler* handler = reinterpret_cast<EventHandler*>(args); | 244 EventHandler* handler = reinterpret_cast<EventHandler*>(args); |
| 272 EventHandlerImplementation* handler_impl = &handler->delegate_; | 245 EventHandlerImplementation* handler_impl = &handler->delegate_; |
| 273 ASSERT(handler_impl != NULL); | 246 ASSERT(handler_impl != NULL); |
| 274 | 247 |
| 275 while (!handler_impl->shutdown_) { | 248 while (!handler_impl->shutdown_) { |
| 276 int64_t millis = handler_impl->GetTimeout(); | 249 int64_t millis = handler_impl->GetTimeout(); |
| 277 ASSERT((millis == kInfinityTimeout) || (millis >= 0)); | 250 ASSERT((millis == kInfinityTimeout) || (millis >= 0)); |
| 278 mx_time_t timeout = | 251 mx_time_t timeout = |
| 279 millis * kMicrosecondsPerMillisecond * kNanosecondsPerMicrosecond; | 252 millis * kMicrosecondsPerMillisecond * kNanosecondsPerMicrosecond; |
| 280 const MagentaWaitManyInfo& info = handler_impl->info(); | 253 const MagentaWaitManyInfo& info = handler_impl->info(); |
| 281 uint32_t result_index; | 254 LOG_INFO("mx_handle_wait_many(%p, %ld, %lld)\n", |
| 282 LOG_INFO("mx_handle_wait_many(%ld, %p, %p, %lld, %p, %p)\n", | 255 info.items(), info.size(), timeout); |
| 283 info.size(), info.handles(), info.signals(), timeout, &result_index, | |
| 284 info.signals_states()); | |
| 285 mx_status_t status = mx_handle_wait_many( | 256 mx_status_t status = mx_handle_wait_many( |
| 257 info.items(), |
| 286 info.size(), | 258 info.size(), |
| 287 info.handles(), | 259 timeout); |
| 288 info.signals(), | |
| 289 timeout, | |
| 290 &result_index, | |
| 291 info.signals_states()); | |
| 292 if ((status != NO_ERROR) && (status != ERR_TIMED_OUT)) { | 260 if ((status != NO_ERROR) && (status != ERR_TIMED_OUT)) { |
| 293 FATAL1("mx_handle_wait_many failed: %s\n", mx_status_get_string(status)); | 261 FATAL1("mx_handle_wait_many failed: %s\n", mx_status_get_string(status)); |
| 294 } else { | 262 } else { |
| 295 LOG_INFO("mx_handle_wait_many returned: %ld\n", status); | 263 LOG_INFO("mx_handle_wait_many returned: %ld\n", status); |
| 296 handler_impl->HandleTimeout(); | 264 handler_impl->HandleTimeout(); |
| 297 handler_impl->HandleEvents(); | 265 handler_impl->HandleEvents(); |
| 298 } | 266 } |
| 299 } | 267 } |
| 300 handler->NotifyShutdownDone(); | 268 handler->NotifyShutdownDone(); |
| 301 LOG_INFO("EventHandlerImplementation notifying about shutdown\n"); | 269 LOG_INFO("EventHandlerImplementation notifying about shutdown\n"); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 321 int64_t data) { | 289 int64_t data) { |
| 322 WakeupHandler(id, dart_port, data); | 290 WakeupHandler(id, dart_port, data); |
| 323 } | 291 } |
| 324 | 292 |
| 325 } // namespace bin | 293 } // namespace bin |
| 326 } // namespace dart | 294 } // namespace dart |
| 327 | 295 |
| 328 #endif // defined(TARGET_OS_FUCHSIA) | 296 #endif // defined(TARGET_OS_FUCHSIA) |
| 329 | 297 |
| 330 #endif // !defined(DART_IO_DISABLED) | 298 #endif // !defined(DART_IO_DISABLED) |
| OLD | NEW |