| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 #include "platform/globals.h" | 5 #include "platform/globals.h" |
| 6 #if defined(TARGET_OS_ANDROID) | 6 #if defined(TARGET_OS_ANDROID) |
| 7 | 7 |
| 8 #include "bin/eventhandler.h" | 8 #include "bin/eventhandler.h" |
| 9 #include "bin/eventhandler_android.h" | 9 #include "bin/eventhandler_android.h" |
| 10 | 10 |
| 11 #include <errno.h> // NOLINT | 11 #include <errno.h> // NOLINT |
| 12 #include <fcntl.h> // NOLINT |
| 12 #include <pthread.h> // NOLINT | 13 #include <pthread.h> // NOLINT |
| 13 #include <stdio.h> // NOLINT | 14 #include <stdio.h> // NOLINT |
| 14 #include <string.h> // NOLINT | 15 #include <string.h> // NOLINT |
| 15 #include <sys/epoll.h> // NOLINT | 16 #include <sys/epoll.h> // NOLINT |
| 16 #include <sys/stat.h> // NOLINT | 17 #include <sys/stat.h> // NOLINT |
| 17 #include <unistd.h> // NOLINT | 18 #include <unistd.h> // NOLINT |
| 18 #include <fcntl.h> // NOLINT | |
| 19 | 19 |
| 20 #include "bin/dartutils.h" | 20 #include "bin/dartutils.h" |
| 21 #include "bin/fdutils.h" | 21 #include "bin/fdutils.h" |
| 22 #include "bin/log.h" | 22 #include "bin/log.h" |
| 23 #include "bin/lockers.h" | 23 #include "bin/lockers.h" |
| 24 #include "bin/socket.h" | 24 #include "bin/socket.h" |
| 25 #include "bin/thread.h" | 25 #include "bin/thread.h" |
| 26 #include "bin/utils.h" | 26 #include "bin/utils.h" |
| 27 #include "platform/hashmap.h" | 27 #include "platform/hashmap.h" |
| 28 #include "platform/utils.h" | 28 #include "platform/utils.h" |
| 29 | 29 |
| 30 | |
| 31 // Android doesn't define EPOLLRDHUP. | 30 // Android doesn't define EPOLLRDHUP. |
| 32 #if !defined(EPOLLRDHUP) | 31 #if !defined(EPOLLRDHUP) |
| 33 #define EPOLLRDHUP 0x2000 | 32 #define EPOLLRDHUP 0x2000 |
| 34 #endif // !defined(EPOLLRDHUP) | 33 #endif // !defined(EPOLLRDHUP) |
| 35 | 34 |
| 36 | |
| 37 namespace dart { | 35 namespace dart { |
| 38 namespace bin { | 36 namespace bin { |
| 39 | 37 |
| 40 | |
| 41 intptr_t DescriptorInfo::GetPollEvents() { | 38 intptr_t DescriptorInfo::GetPollEvents() { |
| 42 // Do not ask for EPOLLERR and EPOLLHUP explicitly as they are | 39 // Do not ask for EPOLLERR and EPOLLHUP explicitly as they are |
| 43 // triggered anyway. | 40 // triggered anyway. |
| 44 intptr_t events = 0; | 41 intptr_t events = 0; |
| 45 if ((Mask() & (1 << kInEvent)) != 0) { | 42 if ((Mask() & (1 << kInEvent)) != 0) { |
| 46 events |= EPOLLIN; | 43 events |= EPOLLIN; |
| 47 } | 44 } |
| 48 if ((Mask() & (1 << kOutEvent)) != 0) { | 45 if ((Mask() & (1 << kOutEvent)) != 0) { |
| 49 events |= EPOLLOUT; | 46 events |= EPOLLOUT; |
| 50 } | 47 } |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 122 EventHandlerImplementation::~EventHandlerImplementation() { | 119 EventHandlerImplementation::~EventHandlerImplementation() { |
| 123 VOID_TEMP_FAILURE_RETRY(close(epoll_fd_)); | 120 VOID_TEMP_FAILURE_RETRY(close(epoll_fd_)); |
| 124 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[0])); | 121 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[0])); |
| 125 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[1])); | 122 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[1])); |
| 126 } | 123 } |
| 127 | 124 |
| 128 | 125 |
| 129 void EventHandlerImplementation::UpdateEpollInstance(intptr_t old_mask, | 126 void EventHandlerImplementation::UpdateEpollInstance(intptr_t old_mask, |
| 130 DescriptorInfo *di) { | 127 DescriptorInfo *di) { |
| 131 intptr_t new_mask = di->Mask(); | 128 intptr_t new_mask = di->Mask(); |
| 132 if (old_mask != 0 && new_mask == 0) { | 129 if ((old_mask != 0) && (new_mask == 0)) { |
| 133 RemoveFromEpollInstance(epoll_fd_, di); | 130 RemoveFromEpollInstance(epoll_fd_, di); |
| 134 } else if (old_mask == 0 && new_mask != 0) { | 131 } else if ((old_mask == 0) && (new_mask != 0)) { |
| 135 AddToEpollInstance(epoll_fd_, di); | 132 AddToEpollInstance(epoll_fd_, di); |
| 136 } else if (old_mask != 0 && new_mask != 0 && old_mask != new_mask) { | 133 } else if ((old_mask != 0) && (new_mask != 0) && (old_mask != new_mask)) { |
| 137 ASSERT(!di->IsListeningSocket()); | 134 ASSERT(!di->IsListeningSocket()); |
| 138 RemoveFromEpollInstance(epoll_fd_, di); | 135 RemoveFromEpollInstance(epoll_fd_, di); |
| 139 AddToEpollInstance(epoll_fd_, di); | 136 AddToEpollInstance(epoll_fd_, di); |
| 140 } | 137 } |
| 141 } | 138 } |
| 142 | 139 |
| 143 | 140 |
| 144 DescriptorInfo* EventHandlerImplementation::GetDescriptorInfo( | 141 DescriptorInfo* EventHandlerImplementation::GetDescriptorInfo( |
| 145 intptr_t fd, bool is_listening) { | 142 intptr_t fd, bool is_listening) { |
| 146 ASSERT(fd >= 0); | 143 ASSERT(fd >= 0); |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 257 intptr_t old_mask = di->Mask(); | 254 intptr_t old_mask = di->Mask(); |
| 258 di->SetPortAndMask(msg[i].dart_port, msg[i].data & EVENT_MASK); | 255 di->SetPortAndMask(msg[i].dart_port, msg[i].data & EVENT_MASK); |
| 259 UpdateEpollInstance(old_mask, di); | 256 UpdateEpollInstance(old_mask, di); |
| 260 } else { | 257 } else { |
| 261 UNREACHABLE(); | 258 UNREACHABLE(); |
| 262 } | 259 } |
| 263 } | 260 } |
| 264 } | 261 } |
| 265 } | 262 } |
| 266 | 263 |
| 264 |
| 267 #ifdef DEBUG_POLL | 265 #ifdef DEBUG_POLL |
| 268 static void PrintEventMask(intptr_t fd, intptr_t events) { | 266 static void PrintEventMask(intptr_t fd, intptr_t events) { |
| 269 Log::Print("%d ", fd); | 267 Log::Print("%d ", fd); |
| 270 if ((events & EPOLLIN) != 0) Log::Print("EPOLLIN "); | 268 if ((events & EPOLLIN) != 0) { |
| 271 if ((events & EPOLLPRI) != 0) Log::Print("EPOLLPRI "); | 269 Log::Print("EPOLLIN "); |
| 272 if ((events & EPOLLOUT) != 0) Log::Print("EPOLLOUT "); | 270 } |
| 273 if ((events & EPOLLERR) != 0) Log::Print("EPOLLERR "); | 271 if ((events & EPOLLPRI) != 0) { |
| 274 if ((events & EPOLLHUP) != 0) Log::Print("EPOLLHUP "); | 272 Log::Print("EPOLLPRI "); |
| 275 if ((events & EPOLLRDHUP) != 0) Log::Print("EPOLLRDHUP "); | 273 } |
| 274 if ((events & EPOLLOUT) != 0) { |
| 275 Log::Print("EPOLLOUT "); |
| 276 } |
| 277 if ((events & EPOLLERR) != 0) { |
| 278 Log::Print("EPOLLERR "); |
| 279 } |
| 280 if ((events & EPOLLHUP) != 0) { |
| 281 Log::Print("EPOLLHUP "); |
| 282 } |
| 283 if ((events & EPOLLRDHUP) != 0) { |
| 284 Log::Print("EPOLLRDHUP "); |
| 285 } |
| 276 int all_events = EPOLLIN | EPOLLPRI | EPOLLOUT | | 286 int all_events = EPOLLIN | EPOLLPRI | EPOLLOUT | |
| 277 EPOLLERR | EPOLLHUP | EPOLLRDHUP; | 287 EPOLLERR | EPOLLHUP | EPOLLRDHUP; |
| 278 if ((events & ~all_events) != 0) { | 288 if ((events & ~all_events) != 0) { |
| 279 Log::Print("(and %08x) ", events & ~all_events); | 289 Log::Print("(and %08x) ", events & ~all_events); |
| 280 } | 290 } |
| 281 Log::Print("(available %d) ", FDUtils::AvailableBytes(fd)); | 291 Log::Print("(available %d) ", FDUtils::AvailableBytes(fd)); |
| 282 | 292 |
| 283 Log::Print("\n"); | 293 Log::Print("\n"); |
| 284 } | 294 } |
| 285 #endif | 295 #endif |
| 286 | 296 |
| 297 |
| 287 intptr_t EventHandlerImplementation::GetPollEvents(intptr_t events, | 298 intptr_t EventHandlerImplementation::GetPollEvents(intptr_t events, |
| 288 DescriptorInfo* di) { | 299 DescriptorInfo* di) { |
| 289 #ifdef DEBUG_POLL | 300 #ifdef DEBUG_POLL |
| 290 PrintEventMask(di->fd(), events); | 301 PrintEventMask(di->fd(), events); |
| 291 #endif | 302 #endif |
| 292 if (events & EPOLLERR) { | 303 if (events & EPOLLERR) { |
| 293 // Return error only if EPOLLIN is present. | 304 // Return error only if EPOLLIN is present. |
| 294 return (events & EPOLLIN) ? (1 << kErrorEvent) : 0; | 305 return (events & EPOLLIN) ? (1 << kErrorEvent) : 0; |
| 295 } | 306 } |
| 296 intptr_t event_mask = 0; | 307 intptr_t event_mask = 0; |
| 297 if (events & EPOLLIN) event_mask |= (1 << kInEvent); | 308 if (events & EPOLLIN) { |
| 298 if (events & EPOLLOUT) event_mask |= (1 << kOutEvent); | 309 event_mask |= (1 << kInEvent); |
| 299 if (events & (EPOLLHUP | EPOLLRDHUP)) event_mask |= (1 << kCloseEvent); | 310 } |
| 311 if (events & EPOLLOUT) { |
| 312 event_mask |= (1 << kOutEvent); |
| 313 } |
| 314 if (events & (EPOLLHUP | EPOLLRDHUP)) { |
| 315 event_mask |= (1 << kCloseEvent); |
| 316 } |
| 300 return event_mask; | 317 return event_mask; |
| 301 } | 318 } |
| 302 | 319 |
| 303 | 320 |
| 304 void EventHandlerImplementation::HandleEvents(struct epoll_event* events, | 321 void EventHandlerImplementation::HandleEvents(struct epoll_event* events, |
| 305 int size) { | 322 int size) { |
| 306 bool interrupt_seen = false; | 323 bool interrupt_seen = false; |
| 307 for (int i = 0; i < size; i++) { | 324 for (int i = 0; i < size; i++) { |
| 308 if (events[i].data.ptr == NULL) { | 325 if (events[i].data.ptr == NULL) { |
| 309 interrupt_seen = true; | 326 interrupt_seen = true; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 353 void EventHandlerImplementation::Poll(uword args) { | 370 void EventHandlerImplementation::Poll(uword args) { |
| 354 ThreadSignalBlocker signal_blocker(SIGPROF); | 371 ThreadSignalBlocker signal_blocker(SIGPROF); |
| 355 static const intptr_t kMaxEvents = 16; | 372 static const intptr_t kMaxEvents = 16; |
| 356 struct epoll_event events[kMaxEvents]; | 373 struct epoll_event events[kMaxEvents]; |
| 357 EventHandler* handler = reinterpret_cast<EventHandler*>(args); | 374 EventHandler* handler = reinterpret_cast<EventHandler*>(args); |
| 358 EventHandlerImplementation* handler_impl = &handler->delegate_; | 375 EventHandlerImplementation* handler_impl = &handler->delegate_; |
| 359 ASSERT(handler_impl != NULL); | 376 ASSERT(handler_impl != NULL); |
| 360 | 377 |
| 361 while (!handler_impl->shutdown_) { | 378 while (!handler_impl->shutdown_) { |
| 362 int64_t millis = handler_impl->GetTimeout(); | 379 int64_t millis = handler_impl->GetTimeout(); |
| 363 ASSERT(millis == kInfinityTimeout || millis >= 0); | 380 ASSERT((millis == kInfinityTimeout) || (millis >= 0)); |
| 364 if (millis > kMaxInt32) millis = kMaxInt32; | 381 if (millis > kMaxInt32) { |
| 382 millis = kMaxInt32; |
| 383 } |
| 365 intptr_t result = TEMP_FAILURE_RETRY_NO_SIGNAL_BLOCKER( | 384 intptr_t result = TEMP_FAILURE_RETRY_NO_SIGNAL_BLOCKER( |
| 366 epoll_wait(handler_impl->epoll_fd_, events, kMaxEvents, millis)); | 385 epoll_wait(handler_impl->epoll_fd_, events, kMaxEvents, millis)); |
| 367 ASSERT(EAGAIN == EWOULDBLOCK); | 386 ASSERT(EAGAIN == EWOULDBLOCK); |
| 368 if (result == -1) { | 387 if (result == -1) { |
| 369 if (errno != EWOULDBLOCK) { | 388 if (errno != EWOULDBLOCK) { |
| 370 perror("Poll failed"); | 389 perror("Poll failed"); |
| 371 } | 390 } |
| 372 } else { | 391 } else { |
| 373 handler_impl->HandleTimeout(); | 392 handler_impl->HandleTimeout(); |
| 374 handler_impl->HandleEvents(events, result); | 393 handler_impl->HandleEvents(events, result); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 407 | 426 |
| 408 uint32_t EventHandlerImplementation::GetHashmapHashFromFd(intptr_t fd) { | 427 uint32_t EventHandlerImplementation::GetHashmapHashFromFd(intptr_t fd) { |
| 409 // The hashmap does not support keys with value 0. | 428 // The hashmap does not support keys with value 0. |
| 410 return dart::Utils::WordHash(fd + 1); | 429 return dart::Utils::WordHash(fd + 1); |
| 411 } | 430 } |
| 412 | 431 |
| 413 } // namespace bin | 432 } // namespace bin |
| 414 } // namespace dart | 433 } // namespace dart |
| 415 | 434 |
| 416 #endif // defined(TARGET_OS_ANDROID) | 435 #endif // defined(TARGET_OS_ANDROID) |
| OLD | NEW |