| 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(HOST_OS_FUCHSIA) | 8 #if defined(HOST_OS_FUCHSIA) |
| 9 | 9 |
| 10 #include "bin/eventhandler.h" | 10 #include "bin/eventhandler.h" |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 // real, and which are ignore-and-continue. | 90 // real, and which are ignore-and-continue. |
| 91 read_events_enabled_ = true; | 91 read_events_enabled_ = true; |
| 92 if (!AsyncWaitLocked(MX_HANDLE_INVALID, POLLIN, wait_key_)) { | 92 if (!AsyncWaitLocked(MX_HANDLE_INVALID, POLLIN, wait_key_)) { |
| 93 LOG_ERR("IOHandle::AsyncWait failed for fd = %ld\n", fd_); | 93 LOG_ERR("IOHandle::AsyncWait failed for fd = %ld\n", fd_); |
| 94 } | 94 } |
| 95 | 95 |
| 96 errno = err; | 96 errno = err; |
| 97 return read_bytes; | 97 return read_bytes; |
| 98 } | 98 } |
| 99 | 99 |
| 100 | |
| 101 intptr_t IOHandle::Write(const void* buffer, intptr_t num_bytes) { | 100 intptr_t IOHandle::Write(const void* buffer, intptr_t num_bytes) { |
| 102 MutexLocker ml(mutex_); | 101 MutexLocker ml(mutex_); |
| 103 const ssize_t written_bytes = | 102 const ssize_t written_bytes = |
| 104 NO_RETRY_EXPECTED(write(fd_, buffer, num_bytes)); | 103 NO_RETRY_EXPECTED(write(fd_, buffer, num_bytes)); |
| 105 const int err = errno; | 104 const int err = errno; |
| 106 LOG_INFO("IOHandle::Write: fd = %ld. wrote %ld bytes\n", fd_, written_bytes); | 105 LOG_INFO("IOHandle::Write: fd = %ld. wrote %ld bytes\n", fd_, written_bytes); |
| 107 | 106 |
| 108 // Resubscribe to write events. | 107 // Resubscribe to write events. |
| 109 write_events_enabled_ = true; | 108 write_events_enabled_ = true; |
| 110 if (!AsyncWaitLocked(MX_HANDLE_INVALID, POLLOUT, wait_key_)) { | 109 if (!AsyncWaitLocked(MX_HANDLE_INVALID, POLLOUT, wait_key_)) { |
| 111 LOG_ERR("IOHandle::AsyncWait failed for fd = %ld\n", fd_); | 110 LOG_ERR("IOHandle::AsyncWait failed for fd = %ld\n", fd_); |
| 112 } | 111 } |
| 113 | 112 |
| 114 errno = err; | 113 errno = err; |
| 115 return written_bytes; | 114 return written_bytes; |
| 116 } | 115 } |
| 117 | 116 |
| 118 | |
| 119 intptr_t IOHandle::Accept(struct sockaddr* addr, socklen_t* addrlen) { | 117 intptr_t IOHandle::Accept(struct sockaddr* addr, socklen_t* addrlen) { |
| 120 MutexLocker ml(mutex_); | 118 MutexLocker ml(mutex_); |
| 121 const intptr_t socket = NO_RETRY_EXPECTED(accept(fd_, addr, addrlen)); | 119 const intptr_t socket = NO_RETRY_EXPECTED(accept(fd_, addr, addrlen)); |
| 122 const int err = errno; | 120 const int err = errno; |
| 123 LOG_INFO("IOHandle::Accept: fd = %ld. socket = %ld\n", fd_, socket); | 121 LOG_INFO("IOHandle::Accept: fd = %ld. socket = %ld\n", fd_, socket); |
| 124 | 122 |
| 125 // Re-subscribe to read events. | 123 // Re-subscribe to read events. |
| 126 read_events_enabled_ = true; | 124 read_events_enabled_ = true; |
| 127 if (!AsyncWaitLocked(MX_HANDLE_INVALID, POLLIN, wait_key_)) { | 125 if (!AsyncWaitLocked(MX_HANDLE_INVALID, POLLIN, wait_key_)) { |
| 128 LOG_ERR("IOHandle::AsyncWait failed for fd = %ld\n", fd_); | 126 LOG_ERR("IOHandle::AsyncWait failed for fd = %ld\n", fd_); |
| 129 } | 127 } |
| 130 | 128 |
| 131 errno = err; | 129 errno = err; |
| 132 return socket; | 130 return socket; |
| 133 } | 131 } |
| 134 | 132 |
| 135 | |
| 136 void IOHandle::Close() { | 133 void IOHandle::Close() { |
| 137 MutexLocker ml(mutex_); | 134 MutexLocker ml(mutex_); |
| 138 VOID_NO_RETRY_EXPECTED(close(fd_)); | 135 VOID_NO_RETRY_EXPECTED(close(fd_)); |
| 139 } | 136 } |
| 140 | 137 |
| 141 | |
| 142 uint32_t IOHandle::MaskToEpollEvents(intptr_t mask) { | 138 uint32_t IOHandle::MaskToEpollEvents(intptr_t mask) { |
| 143 MutexLocker ml(mutex_); | 139 MutexLocker ml(mutex_); |
| 144 // Do not ask for POLLERR and POLLHUP explicitly as they are | 140 // Do not ask for POLLERR and POLLHUP explicitly as they are |
| 145 // triggered anyway. | 141 // triggered anyway. |
| 146 uint32_t events = POLLRDHUP; | 142 uint32_t events = POLLRDHUP; |
| 147 if (read_events_enabled_ && ((mask & (1 << kInEvent)) != 0)) { | 143 if (read_events_enabled_ && ((mask & (1 << kInEvent)) != 0)) { |
| 148 events |= POLLIN; | 144 events |= POLLIN; |
| 149 } | 145 } |
| 150 if (write_events_enabled_ && ((mask & (1 << kOutEvent)) != 0)) { | 146 if (write_events_enabled_ && ((mask & (1 << kOutEvent)) != 0)) { |
| 151 events |= POLLOUT; | 147 events |= POLLOUT; |
| 152 } | 148 } |
| 153 return events; | 149 return events; |
| 154 } | 150 } |
| 155 | 151 |
| 156 | |
| 157 intptr_t IOHandle::EpollEventsToMask(intptr_t events) { | 152 intptr_t IOHandle::EpollEventsToMask(intptr_t events) { |
| 158 if ((events & POLLERR) != 0) { | 153 if ((events & POLLERR) != 0) { |
| 159 // Return error only if POLLIN is present. | 154 // Return error only if POLLIN is present. |
| 160 return ((events & POLLIN) != 0) ? (1 << kErrorEvent) : 0; | 155 return ((events & POLLIN) != 0) ? (1 << kErrorEvent) : 0; |
| 161 } | 156 } |
| 162 intptr_t event_mask = 0; | 157 intptr_t event_mask = 0; |
| 163 if ((events & POLLIN) != 0) { | 158 if ((events & POLLIN) != 0) { |
| 164 event_mask |= (1 << kInEvent); | 159 event_mask |= (1 << kInEvent); |
| 165 } | 160 } |
| 166 if ((events & POLLOUT) != 0) { | 161 if ((events & POLLOUT) != 0) { |
| 167 event_mask |= (1 << kOutEvent); | 162 event_mask |= (1 << kOutEvent); |
| 168 } | 163 } |
| 169 if ((events & (POLLHUP | POLLRDHUP)) != 0) { | 164 if ((events & (POLLHUP | POLLRDHUP)) != 0) { |
| 170 event_mask |= (1 << kCloseEvent); | 165 event_mask |= (1 << kCloseEvent); |
| 171 } | 166 } |
| 172 return event_mask; | 167 return event_mask; |
| 173 } | 168 } |
| 174 | 169 |
| 175 | |
| 176 bool IOHandle::AsyncWaitLocked(mx_handle_t port, | 170 bool IOHandle::AsyncWaitLocked(mx_handle_t port, |
| 177 uint32_t events, | 171 uint32_t events, |
| 178 uint64_t key) { | 172 uint64_t key) { |
| 179 LOG_INFO("IOHandle::AsyncWait: fd = %ld\n", fd_); | 173 LOG_INFO("IOHandle::AsyncWait: fd = %ld\n", fd_); |
| 180 // The call to __mxio_fd_to_io() in the DescriptorInfo constructor may have | 174 // The call to __mxio_fd_to_io() in the DescriptorInfo constructor may have |
| 181 // returned NULL. If it did, propagate the problem up to Dart. | 175 // returned NULL. If it did, propagate the problem up to Dart. |
| 182 if (mxio_ == NULL) { | 176 if (mxio_ == NULL) { |
| 183 LOG_ERR("__mxio_fd_to_io(%d) returned NULL\n", fd_); | 177 LOG_ERR("__mxio_fd_to_io(%d) returned NULL\n", fd_); |
| 184 return false; | 178 return false; |
| 185 } | 179 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 205 mx_status_t status = | 199 mx_status_t status = |
| 206 mx_object_wait_async(handle_, port_, key, signals, MX_WAIT_ASYNC_ONCE); | 200 mx_object_wait_async(handle_, port_, key, signals, MX_WAIT_ASYNC_ONCE); |
| 207 if (status != MX_OK) { | 201 if (status != MX_OK) { |
| 208 LOG_ERR("mx_object_wait_async failed: %s\n", mx_status_get_string(status)); | 202 LOG_ERR("mx_object_wait_async failed: %s\n", mx_status_get_string(status)); |
| 209 return false; | 203 return false; |
| 210 } | 204 } |
| 211 | 205 |
| 212 return true; | 206 return true; |
| 213 } | 207 } |
| 214 | 208 |
| 215 | |
| 216 bool IOHandle::AsyncWait(mx_handle_t port, uint32_t events, uint64_t key) { | 209 bool IOHandle::AsyncWait(mx_handle_t port, uint32_t events, uint64_t key) { |
| 217 MutexLocker ml(mutex_); | 210 MutexLocker ml(mutex_); |
| 218 return AsyncWaitLocked(port, events, key); | 211 return AsyncWaitLocked(port, events, key); |
| 219 } | 212 } |
| 220 | 213 |
| 221 | |
| 222 void IOHandle::CancelWait(mx_handle_t port, uint64_t key) { | 214 void IOHandle::CancelWait(mx_handle_t port, uint64_t key) { |
| 223 MutexLocker ml(mutex_); | 215 MutexLocker ml(mutex_); |
| 224 LOG_INFO("IOHandle::CancelWait: fd = %ld\n", fd_); | 216 LOG_INFO("IOHandle::CancelWait: fd = %ld\n", fd_); |
| 225 ASSERT(port != MX_HANDLE_INVALID); | 217 ASSERT(port != MX_HANDLE_INVALID); |
| 226 ASSERT(handle_ != MX_HANDLE_INVALID); | 218 ASSERT(handle_ != MX_HANDLE_INVALID); |
| 227 mx_status_t status = mx_port_cancel(port, handle_, key); | 219 mx_status_t status = mx_port_cancel(port, handle_, key); |
| 228 if ((status != MX_OK) && (status != MX_ERR_NOT_FOUND)) { | 220 if ((status != MX_OK) && (status != MX_ERR_NOT_FOUND)) { |
| 229 LOG_ERR("mx_port_cancel failed: %s\n", mx_status_get_string(status)); | 221 LOG_ERR("mx_port_cancel failed: %s\n", mx_status_get_string(status)); |
| 230 } | 222 } |
| 231 } | 223 } |
| 232 | 224 |
| 233 | |
| 234 uint32_t IOHandle::WaitEnd(mx_signals_t observed) { | 225 uint32_t IOHandle::WaitEnd(mx_signals_t observed) { |
| 235 MutexLocker ml(mutex_); | 226 MutexLocker ml(mutex_); |
| 236 uint32_t events = 0; | 227 uint32_t events = 0; |
| 237 __mxio_wait_end(mxio_, observed, &events); | 228 __mxio_wait_end(mxio_, observed, &events); |
| 238 return events; | 229 return events; |
| 239 } | 230 } |
| 240 | 231 |
| 241 | |
| 242 intptr_t IOHandle::ToggleEvents(intptr_t event_mask) { | 232 intptr_t IOHandle::ToggleEvents(intptr_t event_mask) { |
| 243 MutexLocker ml(mutex_); | 233 MutexLocker ml(mutex_); |
| 244 if (!write_events_enabled_) { | 234 if (!write_events_enabled_) { |
| 245 LOG_INFO("IOHandle::ToggleEvents: fd = %ld de-asserting write\n", fd_); | 235 LOG_INFO("IOHandle::ToggleEvents: fd = %ld de-asserting write\n", fd_); |
| 246 event_mask = event_mask & ~(1 << kOutEvent); | 236 event_mask = event_mask & ~(1 << kOutEvent); |
| 247 } | 237 } |
| 248 if ((event_mask & (1 << kOutEvent)) != 0) { | 238 if ((event_mask & (1 << kOutEvent)) != 0) { |
| 249 LOG_INFO("IOHandle::ToggleEvents: fd = %ld asserting write and disabling\n", | 239 LOG_INFO("IOHandle::ToggleEvents: fd = %ld asserting write and disabling\n", |
| 250 fd_); | 240 fd_); |
| 251 write_events_enabled_ = false; | 241 write_events_enabled_ = false; |
| 252 } | 242 } |
| 253 if (!read_events_enabled_) { | 243 if (!read_events_enabled_) { |
| 254 LOG_INFO("IOHandle::ToggleEvents: fd=%ld de-asserting read\n", fd_); | 244 LOG_INFO("IOHandle::ToggleEvents: fd=%ld de-asserting read\n", fd_); |
| 255 event_mask = event_mask & ~(1 << kInEvent); | 245 event_mask = event_mask & ~(1 << kInEvent); |
| 256 } | 246 } |
| 257 if ((event_mask & (1 << kInEvent)) != 0) { | 247 if ((event_mask & (1 << kInEvent)) != 0) { |
| 258 LOG_INFO("IOHandle::ToggleEvents: fd = %ld asserting read and disabling\n", | 248 LOG_INFO("IOHandle::ToggleEvents: fd = %ld asserting read and disabling\n", |
| 259 fd_); | 249 fd_); |
| 260 read_events_enabled_ = false; | 250 read_events_enabled_ = false; |
| 261 } | 251 } |
| 262 return event_mask; | 252 return event_mask; |
| 263 } | 253 } |
| 264 | 254 |
| 265 | |
| 266 void EventHandlerImplementation::AddToPort(mx_handle_t port_handle, | 255 void EventHandlerImplementation::AddToPort(mx_handle_t port_handle, |
| 267 DescriptorInfo* di) { | 256 DescriptorInfo* di) { |
| 268 const uint32_t events = di->io_handle()->MaskToEpollEvents(di->Mask()); | 257 const uint32_t events = di->io_handle()->MaskToEpollEvents(di->Mask()); |
| 269 const uint64_t key = reinterpret_cast<uint64_t>(di); | 258 const uint64_t key = reinterpret_cast<uint64_t>(di); |
| 270 if (!di->io_handle()->AsyncWait(port_handle, events, key)) { | 259 if (!di->io_handle()->AsyncWait(port_handle, events, key)) { |
| 271 di->NotifyAllDartPorts(1 << kCloseEvent); | 260 di->NotifyAllDartPorts(1 << kCloseEvent); |
| 272 } | 261 } |
| 273 } | 262 } |
| 274 | 263 |
| 275 | |
| 276 void EventHandlerImplementation::RemoveFromPort(mx_handle_t port_handle, | 264 void EventHandlerImplementation::RemoveFromPort(mx_handle_t port_handle, |
| 277 DescriptorInfo* di) { | 265 DescriptorInfo* di) { |
| 278 const uint64_t key = reinterpret_cast<uint64_t>(di); | 266 const uint64_t key = reinterpret_cast<uint64_t>(di); |
| 279 di->io_handle()->CancelWait(port_handle, key); | 267 di->io_handle()->CancelWait(port_handle, key); |
| 280 } | 268 } |
| 281 | 269 |
| 282 | |
| 283 EventHandlerImplementation::EventHandlerImplementation() | 270 EventHandlerImplementation::EventHandlerImplementation() |
| 284 : socket_map_(&HashMap::SamePointerValue, 16) { | 271 : socket_map_(&HashMap::SamePointerValue, 16) { |
| 285 shutdown_ = false; | 272 shutdown_ = false; |
| 286 // Create the port. | 273 // Create the port. |
| 287 port_handle_ = MX_HANDLE_INVALID; | 274 port_handle_ = MX_HANDLE_INVALID; |
| 288 mx_status_t status = mx_port_create(0, &port_handle_); | 275 mx_status_t status = mx_port_create(0, &port_handle_); |
| 289 if (status != MX_OK) { | 276 if (status != MX_OK) { |
| 290 // This is a FATAL because the VM won't work at all if we can't create this | 277 // This is a FATAL because the VM won't work at all if we can't create this |
| 291 // port. | 278 // port. |
| 292 FATAL1("mx_port_create failed: %s\n", mx_status_get_string(status)); | 279 FATAL1("mx_port_create failed: %s\n", mx_status_get_string(status)); |
| 293 } | 280 } |
| 294 ASSERT(port_handle_ != MX_HANDLE_INVALID); | 281 ASSERT(port_handle_ != MX_HANDLE_INVALID); |
| 295 } | 282 } |
| 296 | 283 |
| 297 | |
| 298 static void DeleteDescriptorInfo(void* info) { | 284 static void DeleteDescriptorInfo(void* info) { |
| 299 DescriptorInfo* di = reinterpret_cast<DescriptorInfo*>(info); | 285 DescriptorInfo* di = reinterpret_cast<DescriptorInfo*>(info); |
| 300 LOG_INFO("Closed %ld\n", di->io_handle()->fd()); | 286 LOG_INFO("Closed %ld\n", di->io_handle()->fd()); |
| 301 di->Close(); | 287 di->Close(); |
| 302 delete di; | 288 delete di; |
| 303 } | 289 } |
| 304 | 290 |
| 305 | |
| 306 EventHandlerImplementation::~EventHandlerImplementation() { | 291 EventHandlerImplementation::~EventHandlerImplementation() { |
| 307 socket_map_.Clear(DeleteDescriptorInfo); | 292 socket_map_.Clear(DeleteDescriptorInfo); |
| 308 mx_handle_close(port_handle_); | 293 mx_handle_close(port_handle_); |
| 309 port_handle_ = MX_HANDLE_INVALID; | 294 port_handle_ = MX_HANDLE_INVALID; |
| 310 } | 295 } |
| 311 | 296 |
| 312 | |
| 313 void EventHandlerImplementation::UpdatePort(intptr_t old_mask, | 297 void EventHandlerImplementation::UpdatePort(intptr_t old_mask, |
| 314 DescriptorInfo* di) { | 298 DescriptorInfo* di) { |
| 315 const intptr_t new_mask = di->Mask(); | 299 const intptr_t new_mask = di->Mask(); |
| 316 if ((old_mask != 0) && (new_mask == 0)) { | 300 if ((old_mask != 0) && (new_mask == 0)) { |
| 317 RemoveFromPort(port_handle_, di); | 301 RemoveFromPort(port_handle_, di); |
| 318 } else if ((old_mask == 0) && (new_mask != 0)) { | 302 } else if ((old_mask == 0) && (new_mask != 0)) { |
| 319 AddToPort(port_handle_, di); | 303 AddToPort(port_handle_, di); |
| 320 } else if ((old_mask != 0) && (new_mask != 0)) { | 304 } else if ((old_mask != 0) && (new_mask != 0)) { |
| 321 ASSERT(!di->IsListeningSocket()); | 305 ASSERT(!di->IsListeningSocket()); |
| 322 RemoveFromPort(port_handle_, di); | 306 RemoveFromPort(port_handle_, di); |
| 323 AddToPort(port_handle_, di); | 307 AddToPort(port_handle_, di); |
| 324 } | 308 } |
| 325 } | 309 } |
| 326 | 310 |
| 327 | |
| 328 DescriptorInfo* EventHandlerImplementation::GetDescriptorInfo( | 311 DescriptorInfo* EventHandlerImplementation::GetDescriptorInfo( |
| 329 intptr_t fd, | 312 intptr_t fd, |
| 330 bool is_listening) { | 313 bool is_listening) { |
| 331 IOHandle* handle = reinterpret_cast<IOHandle*>(fd); | 314 IOHandle* handle = reinterpret_cast<IOHandle*>(fd); |
| 332 ASSERT(handle->fd() >= 0); | 315 ASSERT(handle->fd() >= 0); |
| 333 HashMap::Entry* entry = | 316 HashMap::Entry* entry = |
| 334 socket_map_.Lookup(GetHashmapKeyFromFd(handle->fd()), | 317 socket_map_.Lookup(GetHashmapKeyFromFd(handle->fd()), |
| 335 GetHashmapHashFromFd(handle->fd()), true); | 318 GetHashmapHashFromFd(handle->fd()), true); |
| 336 ASSERT(entry != NULL); | 319 ASSERT(entry != NULL); |
| 337 DescriptorInfo* di = reinterpret_cast<DescriptorInfo*>(entry->value); | 320 DescriptorInfo* di = reinterpret_cast<DescriptorInfo*>(entry->value); |
| 338 if (di == NULL) { | 321 if (di == NULL) { |
| 339 // If there is no data in the hash map for this file descriptor a | 322 // If there is no data in the hash map for this file descriptor a |
| 340 // new DescriptorInfo for the file descriptor is inserted. | 323 // new DescriptorInfo for the file descriptor is inserted. |
| 341 if (is_listening) { | 324 if (is_listening) { |
| 342 di = new DescriptorInfoMultiple(fd); | 325 di = new DescriptorInfoMultiple(fd); |
| 343 } else { | 326 } else { |
| 344 di = new DescriptorInfoSingle(fd); | 327 di = new DescriptorInfoSingle(fd); |
| 345 } | 328 } |
| 346 entry->value = di; | 329 entry->value = di; |
| 347 } | 330 } |
| 348 ASSERT(fd == di->fd()); | 331 ASSERT(fd == di->fd()); |
| 349 return di; | 332 return di; |
| 350 } | 333 } |
| 351 | 334 |
| 352 | |
| 353 void EventHandlerImplementation::WakeupHandler(intptr_t id, | 335 void EventHandlerImplementation::WakeupHandler(intptr_t id, |
| 354 Dart_Port dart_port, | 336 Dart_Port dart_port, |
| 355 int64_t data) { | 337 int64_t data) { |
| 356 COMPILE_ASSERT(sizeof(InterruptMessage) <= sizeof(mx_packet_user_t)); | 338 COMPILE_ASSERT(sizeof(InterruptMessage) <= sizeof(mx_packet_user_t)); |
| 357 mx_port_packet_t pkt; | 339 mx_port_packet_t pkt; |
| 358 InterruptMessage* msg = reinterpret_cast<InterruptMessage*>(&pkt.user); | 340 InterruptMessage* msg = reinterpret_cast<InterruptMessage*>(&pkt.user); |
| 359 pkt.key = kInterruptPacketKey; | 341 pkt.key = kInterruptPacketKey; |
| 360 msg->id = id; | 342 msg->id = id; |
| 361 msg->dart_port = dart_port; | 343 msg->dart_port = dart_port; |
| 362 msg->data = data; | 344 msg->data = data; |
| 363 mx_status_t status = | 345 mx_status_t status = |
| 364 mx_port_queue(port_handle_, reinterpret_cast<void*>(&pkt), 0); | 346 mx_port_queue(port_handle_, reinterpret_cast<void*>(&pkt), 0); |
| 365 if (status != MX_OK) { | 347 if (status != MX_OK) { |
| 366 // This is a FATAL because the VM won't work at all if we can't send any | 348 // This is a FATAL because the VM won't work at all if we can't send any |
| 367 // messages to the EventHandler thread. | 349 // messages to the EventHandler thread. |
| 368 FATAL1("mx_port_queue failed: %s\n", mx_status_get_string(status)); | 350 FATAL1("mx_port_queue failed: %s\n", mx_status_get_string(status)); |
| 369 } | 351 } |
| 370 } | 352 } |
| 371 | 353 |
| 372 | |
| 373 void EventHandlerImplementation::HandleInterrupt(InterruptMessage* msg) { | 354 void EventHandlerImplementation::HandleInterrupt(InterruptMessage* msg) { |
| 374 if (msg->id == kTimerId) { | 355 if (msg->id == kTimerId) { |
| 375 LOG_INFO("HandleInterrupt read timer update\n"); | 356 LOG_INFO("HandleInterrupt read timer update\n"); |
| 376 timeout_queue_.UpdateTimeout(msg->dart_port, msg->data); | 357 timeout_queue_.UpdateTimeout(msg->dart_port, msg->data); |
| 377 return; | 358 return; |
| 378 } else if (msg->id == kShutdownId) { | 359 } else if (msg->id == kShutdownId) { |
| 379 LOG_INFO("HandleInterrupt read shutdown\n"); | 360 LOG_INFO("HandleInterrupt read shutdown\n"); |
| 380 shutdown_ = true; | 361 shutdown_ = true; |
| 381 return; | 362 return; |
| 382 } | 363 } |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 454 const intptr_t old_mask = di->Mask(); | 435 const intptr_t old_mask = di->Mask(); |
| 455 LOG_INFO("\t Set Event Mask: %ld: %lx %lx\n", fd, old_mask, | 436 LOG_INFO("\t Set Event Mask: %ld: %lx %lx\n", fd, old_mask, |
| 456 msg->data & EVENT_MASK); | 437 msg->data & EVENT_MASK); |
| 457 di->SetPortAndMask(msg->dart_port, msg->data & EVENT_MASK); | 438 di->SetPortAndMask(msg->dart_port, msg->data & EVENT_MASK); |
| 458 UpdatePort(old_mask, di); | 439 UpdatePort(old_mask, di); |
| 459 } else { | 440 } else { |
| 460 UNREACHABLE(); | 441 UNREACHABLE(); |
| 461 } | 442 } |
| 462 } | 443 } |
| 463 | 444 |
| 464 | |
| 465 void EventHandlerImplementation::HandlePacket(mx_port_packet_t* pkt) { | 445 void EventHandlerImplementation::HandlePacket(mx_port_packet_t* pkt) { |
| 466 LOG_INFO("HandlePacket: Got event packet: key=%lx\n", pkt->key); | 446 LOG_INFO("HandlePacket: Got event packet: key=%lx\n", pkt->key); |
| 467 LOG_INFO("HandlePacket: Got event packet: type=%lx\n", pkt->type); | 447 LOG_INFO("HandlePacket: Got event packet: type=%lx\n", pkt->type); |
| 468 LOG_INFO("HandlePacket: Got event packet: status=%ld\n", pkt->status); | 448 LOG_INFO("HandlePacket: Got event packet: status=%ld\n", pkt->status); |
| 469 if (pkt->type == MX_PKT_TYPE_USER) { | 449 if (pkt->type == MX_PKT_TYPE_USER) { |
| 470 ASSERT(pkt->key == kInterruptPacketKey); | 450 ASSERT(pkt->key == kInterruptPacketKey); |
| 471 InterruptMessage* msg = reinterpret_cast<InterruptMessage*>(&pkt->user); | 451 InterruptMessage* msg = reinterpret_cast<InterruptMessage*>(&pkt->user); |
| 472 HandleInterrupt(msg); | 452 HandleInterrupt(msg); |
| 473 return; | 453 return; |
| 474 } | 454 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 492 if (!success) { | 472 if (!success) { |
| 493 // This can happen if e.g. the isolate that owns the port has died | 473 // This can happen if e.g. the isolate that owns the port has died |
| 494 // for some reason. | 474 // for some reason. |
| 495 LOG_INFO("Failed to post event to port %ld\n", port); | 475 LOG_INFO("Failed to post event to port %ld\n", port); |
| 496 } | 476 } |
| 497 } | 477 } |
| 498 } | 478 } |
| 499 UpdatePort(old_mask, di); | 479 UpdatePort(old_mask, di); |
| 500 } | 480 } |
| 501 | 481 |
| 502 | |
| 503 int64_t EventHandlerImplementation::GetTimeout() const { | 482 int64_t EventHandlerImplementation::GetTimeout() const { |
| 504 if (!timeout_queue_.HasTimeout()) { | 483 if (!timeout_queue_.HasTimeout()) { |
| 505 return kInfinityTimeout; | 484 return kInfinityTimeout; |
| 506 } | 485 } |
| 507 int64_t millis = | 486 int64_t millis = |
| 508 timeout_queue_.CurrentTimeout() - TimerUtils::GetCurrentMonotonicMillis(); | 487 timeout_queue_.CurrentTimeout() - TimerUtils::GetCurrentMonotonicMillis(); |
| 509 return (millis < 0) ? 0 : millis; | 488 return (millis < 0) ? 0 : millis; |
| 510 } | 489 } |
| 511 | 490 |
| 512 | |
| 513 void EventHandlerImplementation::HandleTimeout() { | 491 void EventHandlerImplementation::HandleTimeout() { |
| 514 if (timeout_queue_.HasTimeout()) { | 492 if (timeout_queue_.HasTimeout()) { |
| 515 int64_t millis = timeout_queue_.CurrentTimeout() - | 493 int64_t millis = timeout_queue_.CurrentTimeout() - |
| 516 TimerUtils::GetCurrentMonotonicMillis(); | 494 TimerUtils::GetCurrentMonotonicMillis(); |
| 517 if (millis <= 0) { | 495 if (millis <= 0) { |
| 518 DartUtils::PostNull(timeout_queue_.CurrentPort()); | 496 DartUtils::PostNull(timeout_queue_.CurrentPort()); |
| 519 timeout_queue_.RemoveCurrent(); | 497 timeout_queue_.RemoveCurrent(); |
| 520 } | 498 } |
| 521 } | 499 } |
| 522 } | 500 } |
| 523 | 501 |
| 524 | |
| 525 void EventHandlerImplementation::Poll(uword args) { | 502 void EventHandlerImplementation::Poll(uword args) { |
| 526 EventHandler* handler = reinterpret_cast<EventHandler*>(args); | 503 EventHandler* handler = reinterpret_cast<EventHandler*>(args); |
| 527 EventHandlerImplementation* handler_impl = &handler->delegate_; | 504 EventHandlerImplementation* handler_impl = &handler->delegate_; |
| 528 ASSERT(handler_impl != NULL); | 505 ASSERT(handler_impl != NULL); |
| 529 | 506 |
| 530 mx_port_packet_t pkt; | 507 mx_port_packet_t pkt; |
| 531 while (!handler_impl->shutdown_) { | 508 while (!handler_impl->shutdown_) { |
| 532 int64_t millis = handler_impl->GetTimeout(); | 509 int64_t millis = handler_impl->GetTimeout(); |
| 533 ASSERT((millis == kInfinityTimeout) || (millis >= 0)); | 510 ASSERT((millis == kInfinityTimeout) || (millis >= 0)); |
| 534 | 511 |
| 535 LOG_INFO("mx_port_wait(millis = %ld)\n", millis); | 512 LOG_INFO("mx_port_wait(millis = %ld)\n", millis); |
| 536 mx_status_t status = mx_port_wait(handler_impl->port_handle_, | 513 mx_status_t status = mx_port_wait(handler_impl->port_handle_, |
| 537 millis == kInfinityTimeout | 514 millis == kInfinityTimeout |
| 538 ? MX_TIME_INFINITE | 515 ? MX_TIME_INFINITE |
| 539 : mx_deadline_after(MX_MSEC(millis)), | 516 : mx_deadline_after(MX_MSEC(millis)), |
| 540 reinterpret_cast<void*>(&pkt), 0); | 517 reinterpret_cast<void*>(&pkt), 0); |
| 541 if (status == MX_ERR_TIMED_OUT) { | 518 if (status == MX_ERR_TIMED_OUT) { |
| 542 handler_impl->HandleTimeout(); | 519 handler_impl->HandleTimeout(); |
| 543 } else if (status != MX_OK) { | 520 } else if (status != MX_OK) { |
| 544 FATAL1("mx_port_wait failed: %s\n", mx_status_get_string(status)); | 521 FATAL1("mx_port_wait failed: %s\n", mx_status_get_string(status)); |
| 545 } else { | 522 } else { |
| 546 handler_impl->HandleTimeout(); | 523 handler_impl->HandleTimeout(); |
| 547 handler_impl->HandlePacket(&pkt); | 524 handler_impl->HandlePacket(&pkt); |
| 548 } | 525 } |
| 549 } | 526 } |
| 550 DEBUG_ASSERT(ReferenceCounted<Socket>::instances() == 0); | 527 DEBUG_ASSERT(ReferenceCounted<Socket>::instances() == 0); |
| 551 handler->NotifyShutdownDone(); | 528 handler->NotifyShutdownDone(); |
| 552 } | 529 } |
| 553 | 530 |
| 554 | |
| 555 void EventHandlerImplementation::Start(EventHandler* handler) { | 531 void EventHandlerImplementation::Start(EventHandler* handler) { |
| 556 int result = Thread::Start(&EventHandlerImplementation::Poll, | 532 int result = Thread::Start(&EventHandlerImplementation::Poll, |
| 557 reinterpret_cast<uword>(handler)); | 533 reinterpret_cast<uword>(handler)); |
| 558 if (result != 0) { | 534 if (result != 0) { |
| 559 FATAL1("Failed to start event handler thread %d", result); | 535 FATAL1("Failed to start event handler thread %d", result); |
| 560 } | 536 } |
| 561 } | 537 } |
| 562 | 538 |
| 563 | |
| 564 void EventHandlerImplementation::Shutdown() { | 539 void EventHandlerImplementation::Shutdown() { |
| 565 SendData(kShutdownId, 0, 0); | 540 SendData(kShutdownId, 0, 0); |
| 566 } | 541 } |
| 567 | 542 |
| 568 | |
| 569 void EventHandlerImplementation::SendData(intptr_t id, | 543 void EventHandlerImplementation::SendData(intptr_t id, |
| 570 Dart_Port dart_port, | 544 Dart_Port dart_port, |
| 571 int64_t data) { | 545 int64_t data) { |
| 572 WakeupHandler(id, dart_port, data); | 546 WakeupHandler(id, dart_port, data); |
| 573 } | 547 } |
| 574 | 548 |
| 575 void* EventHandlerImplementation::GetHashmapKeyFromFd(intptr_t fd) { | 549 void* EventHandlerImplementation::GetHashmapKeyFromFd(intptr_t fd) { |
| 576 // The hashmap does not support keys with value 0. | 550 // The hashmap does not support keys with value 0. |
| 577 return reinterpret_cast<void*>(fd + 1); | 551 return reinterpret_cast<void*>(fd + 1); |
| 578 } | 552 } |
| 579 | 553 |
| 580 | |
| 581 uint32_t EventHandlerImplementation::GetHashmapHashFromFd(intptr_t fd) { | 554 uint32_t EventHandlerImplementation::GetHashmapHashFromFd(intptr_t fd) { |
| 582 // The hashmap does not support keys with value 0. | 555 // The hashmap does not support keys with value 0. |
| 583 return dart::Utils::WordHash(fd + 1); | 556 return dart::Utils::WordHash(fd + 1); |
| 584 } | 557 } |
| 585 | 558 |
| 586 } // namespace bin | 559 } // namespace bin |
| 587 } // namespace dart | 560 } // namespace dart |
| 588 | 561 |
| 589 #endif // defined(HOST_OS_FUCHSIA) | 562 #endif // defined(HOST_OS_FUCHSIA) |
| 590 | 563 |
| 591 #endif // !defined(DART_IO_DISABLED) | 564 #endif // !defined(DART_IO_DISABLED) |
| OLD | NEW |