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