| 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 #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_ANDROID) | 8 #if defined(HOST_OS_ANDROID) |
| 9 | 9 |
| 10 #include "bin/eventhandler.h" | 10 #include "bin/eventhandler.h" |
| 11 #include "bin/eventhandler_android.h" | 11 #include "bin/eventhandler_android.h" |
| 12 | 12 |
| 13 #include <errno.h> // NOLINT | 13 #include <errno.h> // NOLINT |
| 14 #include <fcntl.h> // NOLINT | 14 #include <fcntl.h> // NOLINT |
| 15 #include <pthread.h> // NOLINT | 15 #include <pthread.h> // NOLINT |
| 16 #include <stdio.h> // NOLINT | 16 #include <stdio.h> // NOLINT |
| 17 #include <string.h> // NOLINT | 17 #include <string.h> // NOLINT |
| 18 #include <sys/epoll.h> // NOLINT | 18 #include <sys/epoll.h> // NOLINT |
| 19 #include <sys/stat.h> // NOLINT | 19 #include <sys/stat.h> // NOLINT |
| 20 #include <unistd.h> // NOLINT | 20 #include <unistd.h> // NOLINT |
| 21 | 21 |
| 22 #include "bin/dartutils.h" | 22 #include "bin/dartutils.h" |
| 23 #include "bin/fdutils.h" | 23 #include "bin/fdutils.h" |
| 24 #include "bin/lockers.h" |
| 24 #include "bin/log.h" | 25 #include "bin/log.h" |
| 25 #include "bin/lockers.h" | |
| 26 #include "bin/socket.h" | 26 #include "bin/socket.h" |
| 27 #include "bin/thread.h" | 27 #include "bin/thread.h" |
| 28 #include "bin/utils.h" | 28 #include "bin/utils.h" |
| 29 #include "platform/hashmap.h" | 29 #include "platform/hashmap.h" |
| 30 #include "platform/utils.h" | 30 #include "platform/utils.h" |
| 31 | 31 |
| 32 // Android doesn't define EPOLLRDHUP. | 32 // Android doesn't define EPOLLRDHUP. |
| 33 #if !defined(EPOLLRDHUP) | 33 #if !defined(EPOLLRDHUP) |
| 34 #define EPOLLRDHUP 0x2000 | 34 #define EPOLLRDHUP 0x2000 |
| 35 #endif // !defined(EPOLLRDHUP) | 35 #endif // !defined(EPOLLRDHUP) |
| 36 | 36 |
| 37 namespace dart { | 37 namespace dart { |
| 38 namespace bin { | 38 namespace bin { |
| 39 | 39 |
| 40 intptr_t DescriptorInfo::GetPollEvents() { | 40 intptr_t DescriptorInfo::GetPollEvents() { |
| 41 // Do not ask for EPOLLERR and EPOLLHUP explicitly as they are | 41 // Do not ask for EPOLLERR and EPOLLHUP explicitly as they are |
| 42 // triggered anyway. | 42 // triggered anyway. |
| 43 intptr_t events = 0; | 43 intptr_t events = 0; |
| 44 if ((Mask() & (1 << kInEvent)) != 0) { | 44 if ((Mask() & (1 << kInEvent)) != 0) { |
| 45 events |= EPOLLIN; | 45 events |= EPOLLIN; |
| 46 } | 46 } |
| 47 if ((Mask() & (1 << kOutEvent)) != 0) { | 47 if ((Mask() & (1 << kOutEvent)) != 0) { |
| 48 events |= EPOLLOUT; | 48 events |= EPOLLOUT; |
| 49 } | 49 } |
| 50 return events; | 50 return events; |
| 51 } | 51 } |
| 52 | 52 |
| 53 | |
| 54 // Unregister the file descriptor for a DescriptorInfo structure with | 53 // Unregister the file descriptor for a DescriptorInfo structure with |
| 55 // epoll. | 54 // epoll. |
| 56 static void RemoveFromEpollInstance(intptr_t epoll_fd_, DescriptorInfo* di) { | 55 static void RemoveFromEpollInstance(intptr_t epoll_fd_, DescriptorInfo* di) { |
| 57 VOID_NO_RETRY_EXPECTED(epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, di->fd(), NULL)); | 56 VOID_NO_RETRY_EXPECTED(epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, di->fd(), NULL)); |
| 58 } | 57 } |
| 59 | 58 |
| 60 | |
| 61 static void AddToEpollInstance(intptr_t epoll_fd_, DescriptorInfo* di) { | 59 static void AddToEpollInstance(intptr_t epoll_fd_, DescriptorInfo* di) { |
| 62 struct epoll_event event; | 60 struct epoll_event event; |
| 63 event.events = EPOLLRDHUP | di->GetPollEvents(); | 61 event.events = EPOLLRDHUP | di->GetPollEvents(); |
| 64 if (!di->IsListeningSocket()) { | 62 if (!di->IsListeningSocket()) { |
| 65 event.events |= EPOLLET; | 63 event.events |= EPOLLET; |
| 66 } | 64 } |
| 67 event.data.ptr = di; | 65 event.data.ptr = di; |
| 68 int status = | 66 int status = |
| 69 NO_RETRY_EXPECTED(epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, di->fd(), &event)); | 67 NO_RETRY_EXPECTED(epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, di->fd(), &event)); |
| 70 if (status == -1) { | 68 if (status == -1) { |
| 71 // TODO(dart:io): Verify that the dart end is handling this correctly. | 69 // TODO(dart:io): Verify that the dart end is handling this correctly. |
| 72 | 70 |
| 73 // Epoll does not accept the file descriptor. It could be due to | 71 // Epoll does not accept the file descriptor. It could be due to |
| 74 // already closed file descriptor, or unuspported devices, such | 72 // already closed file descriptor, or unuspported devices, such |
| 75 // as /dev/null. In such case, mark the file descriptor as closed, | 73 // as /dev/null. In such case, mark the file descriptor as closed, |
| 76 // so dart will handle it accordingly. | 74 // so dart will handle it accordingly. |
| 77 di->NotifyAllDartPorts(1 << kCloseEvent); | 75 di->NotifyAllDartPorts(1 << kCloseEvent); |
| 78 } | 76 } |
| 79 } | 77 } |
| 80 | 78 |
| 81 | |
| 82 EventHandlerImplementation::EventHandlerImplementation() | 79 EventHandlerImplementation::EventHandlerImplementation() |
| 83 : socket_map_(&HashMap::SamePointerValue, 16) { | 80 : socket_map_(&HashMap::SamePointerValue, 16) { |
| 84 intptr_t result; | 81 intptr_t result; |
| 85 result = NO_RETRY_EXPECTED(pipe(interrupt_fds_)); | 82 result = NO_RETRY_EXPECTED(pipe(interrupt_fds_)); |
| 86 if (result != 0) { | 83 if (result != 0) { |
| 87 FATAL("Pipe creation failed"); | 84 FATAL("Pipe creation failed"); |
| 88 } | 85 } |
| 89 if (!FDUtils::SetNonBlocking(interrupt_fds_[0])) { | 86 if (!FDUtils::SetNonBlocking(interrupt_fds_[0])) { |
| 90 FATAL("Failed to set pipe fd non blocking\n"); | 87 FATAL("Failed to set pipe fd non blocking\n"); |
| 91 } | 88 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 110 struct epoll_event event; | 107 struct epoll_event event; |
| 111 event.events = EPOLLIN; | 108 event.events = EPOLLIN; |
| 112 event.data.ptr = NULL; | 109 event.data.ptr = NULL; |
| 113 int status = NO_RETRY_EXPECTED( | 110 int status = NO_RETRY_EXPECTED( |
| 114 epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, interrupt_fds_[0], &event)); | 111 epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, interrupt_fds_[0], &event)); |
| 115 if (status == -1) { | 112 if (status == -1) { |
| 116 FATAL("Failed adding interrupt fd to epoll instance"); | 113 FATAL("Failed adding interrupt fd to epoll instance"); |
| 117 } | 114 } |
| 118 } | 115 } |
| 119 | 116 |
| 120 | |
| 121 static void DeleteDescriptorInfo(void* info) { | 117 static void DeleteDescriptorInfo(void* info) { |
| 122 DescriptorInfo* di = reinterpret_cast<DescriptorInfo*>(info); | 118 DescriptorInfo* di = reinterpret_cast<DescriptorInfo*>(info); |
| 123 di->Close(); | 119 di->Close(); |
| 124 delete di; | 120 delete di; |
| 125 } | 121 } |
| 126 | 122 |
| 127 | |
| 128 EventHandlerImplementation::~EventHandlerImplementation() { | 123 EventHandlerImplementation::~EventHandlerImplementation() { |
| 129 socket_map_.Clear(DeleteDescriptorInfo); | 124 socket_map_.Clear(DeleteDescriptorInfo); |
| 130 VOID_TEMP_FAILURE_RETRY(close(epoll_fd_)); | 125 VOID_TEMP_FAILURE_RETRY(close(epoll_fd_)); |
| 131 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[0])); | 126 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[0])); |
| 132 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[1])); | 127 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[1])); |
| 133 } | 128 } |
| 134 | 129 |
| 135 | |
| 136 void EventHandlerImplementation::UpdateEpollInstance(intptr_t old_mask, | 130 void EventHandlerImplementation::UpdateEpollInstance(intptr_t old_mask, |
| 137 DescriptorInfo* di) { | 131 DescriptorInfo* di) { |
| 138 intptr_t new_mask = di->Mask(); | 132 intptr_t new_mask = di->Mask(); |
| 139 if ((old_mask != 0) && (new_mask == 0)) { | 133 if ((old_mask != 0) && (new_mask == 0)) { |
| 140 RemoveFromEpollInstance(epoll_fd_, di); | 134 RemoveFromEpollInstance(epoll_fd_, di); |
| 141 } else if ((old_mask == 0) && (new_mask != 0)) { | 135 } else if ((old_mask == 0) && (new_mask != 0)) { |
| 142 AddToEpollInstance(epoll_fd_, di); | 136 AddToEpollInstance(epoll_fd_, di); |
| 143 } else if ((old_mask != 0) && (new_mask != 0) && (old_mask != new_mask)) { | 137 } else if ((old_mask != 0) && (new_mask != 0) && (old_mask != new_mask)) { |
| 144 ASSERT(!di->IsListeningSocket()); | 138 ASSERT(!di->IsListeningSocket()); |
| 145 RemoveFromEpollInstance(epoll_fd_, di); | 139 RemoveFromEpollInstance(epoll_fd_, di); |
| 146 AddToEpollInstance(epoll_fd_, di); | 140 AddToEpollInstance(epoll_fd_, di); |
| 147 } | 141 } |
| 148 } | 142 } |
| 149 | 143 |
| 150 | |
| 151 DescriptorInfo* EventHandlerImplementation::GetDescriptorInfo( | 144 DescriptorInfo* EventHandlerImplementation::GetDescriptorInfo( |
| 152 intptr_t fd, | 145 intptr_t fd, |
| 153 bool is_listening) { | 146 bool is_listening) { |
| 154 ASSERT(fd >= 0); | 147 ASSERT(fd >= 0); |
| 155 HashMap::Entry* entry = socket_map_.Lookup(GetHashmapKeyFromFd(fd), | 148 HashMap::Entry* entry = socket_map_.Lookup(GetHashmapKeyFromFd(fd), |
| 156 GetHashmapHashFromFd(fd), true); | 149 GetHashmapHashFromFd(fd), true); |
| 157 ASSERT(entry != NULL); | 150 ASSERT(entry != NULL); |
| 158 DescriptorInfo* di = reinterpret_cast<DescriptorInfo*>(entry->value); | 151 DescriptorInfo* di = reinterpret_cast<DescriptorInfo*>(entry->value); |
| 159 if (di == NULL) { | 152 if (di == NULL) { |
| 160 // If there is no data in the hash map for this file descriptor a | 153 // If there is no data in the hash map for this file descriptor a |
| 161 // new DescriptorInfo for the file descriptor is inserted. | 154 // new DescriptorInfo for the file descriptor is inserted. |
| 162 if (is_listening) { | 155 if (is_listening) { |
| 163 di = new DescriptorInfoMultiple(fd); | 156 di = new DescriptorInfoMultiple(fd); |
| 164 } else { | 157 } else { |
| 165 di = new DescriptorInfoSingle(fd); | 158 di = new DescriptorInfoSingle(fd); |
| 166 } | 159 } |
| 167 entry->value = di; | 160 entry->value = di; |
| 168 } | 161 } |
| 169 ASSERT(fd == di->fd()); | 162 ASSERT(fd == di->fd()); |
| 170 return di; | 163 return di; |
| 171 } | 164 } |
| 172 | 165 |
| 173 | |
| 174 void EventHandlerImplementation::WakeupHandler(intptr_t id, | 166 void EventHandlerImplementation::WakeupHandler(intptr_t id, |
| 175 Dart_Port dart_port, | 167 Dart_Port dart_port, |
| 176 int64_t data) { | 168 int64_t data) { |
| 177 InterruptMessage msg; | 169 InterruptMessage msg; |
| 178 msg.id = id; | 170 msg.id = id; |
| 179 msg.dart_port = dart_port; | 171 msg.dart_port = dart_port; |
| 180 msg.data = data; | 172 msg.data = data; |
| 181 // WriteToBlocking will write up to 512 bytes atomically, and since our msg | 173 // WriteToBlocking will write up to 512 bytes atomically, and since our msg |
| 182 // is smaller than 512, we don't need a thread lock. | 174 // is smaller than 512, we don't need a thread lock. |
| 183 // See: http://linux.die.net/man/7/pipe, section 'Pipe_buf'. | 175 // See: http://linux.die.net/man/7/pipe, section 'Pipe_buf'. |
| 184 ASSERT(kInterruptMessageSize < PIPE_BUF); | 176 ASSERT(kInterruptMessageSize < PIPE_BUF); |
| 185 intptr_t result = | 177 intptr_t result = |
| 186 FDUtils::WriteToBlocking(interrupt_fds_[1], &msg, kInterruptMessageSize); | 178 FDUtils::WriteToBlocking(interrupt_fds_[1], &msg, kInterruptMessageSize); |
| 187 if (result != kInterruptMessageSize) { | 179 if (result != kInterruptMessageSize) { |
| 188 if (result == -1) { | 180 if (result == -1) { |
| 189 perror("Interrupt message failure:"); | 181 perror("Interrupt message failure:"); |
| 190 } | 182 } |
| 191 FATAL1("Interrupt message failure. Wrote %" Pd " bytes.", result); | 183 FATAL1("Interrupt message failure. Wrote %" Pd " bytes.", result); |
| 192 } | 184 } |
| 193 } | 185 } |
| 194 | 186 |
| 195 | |
| 196 void EventHandlerImplementation::HandleInterruptFd() { | 187 void EventHandlerImplementation::HandleInterruptFd() { |
| 197 const intptr_t MAX_MESSAGES = kInterruptMessageSize; | 188 const intptr_t MAX_MESSAGES = kInterruptMessageSize; |
| 198 InterruptMessage msg[MAX_MESSAGES]; | 189 InterruptMessage msg[MAX_MESSAGES]; |
| 199 ssize_t bytes = TEMP_FAILURE_RETRY_NO_SIGNAL_BLOCKER( | 190 ssize_t bytes = TEMP_FAILURE_RETRY_NO_SIGNAL_BLOCKER( |
| 200 read(interrupt_fds_[0], msg, MAX_MESSAGES * kInterruptMessageSize)); | 191 read(interrupt_fds_[0], msg, MAX_MESSAGES * kInterruptMessageSize)); |
| 201 for (ssize_t i = 0; i < bytes / kInterruptMessageSize; i++) { | 192 for (ssize_t i = 0; i < bytes / kInterruptMessageSize; i++) { |
| 202 if (msg[i].id == kTimerId) { | 193 if (msg[i].id == kTimerId) { |
| 203 timeout_queue_.UpdateTimeout(msg[i].dart_port, msg[i].data); | 194 timeout_queue_.UpdateTimeout(msg[i].dart_port, msg[i].data); |
| 204 } else if (msg[i].id == kShutdownId) { | 195 } else if (msg[i].id == kShutdownId) { |
| 205 shutdown_ = true; | 196 shutdown_ = true; |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 269 intptr_t old_mask = di->Mask(); | 260 intptr_t old_mask = di->Mask(); |
| 270 di->SetPortAndMask(msg[i].dart_port, msg[i].data & EVENT_MASK); | 261 di->SetPortAndMask(msg[i].dart_port, msg[i].data & EVENT_MASK); |
| 271 UpdateEpollInstance(old_mask, di); | 262 UpdateEpollInstance(old_mask, di); |
| 272 } else { | 263 } else { |
| 273 UNREACHABLE(); | 264 UNREACHABLE(); |
| 274 } | 265 } |
| 275 } | 266 } |
| 276 } | 267 } |
| 277 } | 268 } |
| 278 | 269 |
| 279 | |
| 280 #ifdef DEBUG_POLL | 270 #ifdef DEBUG_POLL |
| 281 static void PrintEventMask(intptr_t fd, intptr_t events) { | 271 static void PrintEventMask(intptr_t fd, intptr_t events) { |
| 282 Log::Print("%d ", fd); | 272 Log::Print("%d ", fd); |
| 283 if ((events & EPOLLIN) != 0) { | 273 if ((events & EPOLLIN) != 0) { |
| 284 Log::Print("EPOLLIN "); | 274 Log::Print("EPOLLIN "); |
| 285 } | 275 } |
| 286 if ((events & EPOLLPRI) != 0) { | 276 if ((events & EPOLLPRI) != 0) { |
| 287 Log::Print("EPOLLPRI "); | 277 Log::Print("EPOLLPRI "); |
| 288 } | 278 } |
| 289 if ((events & EPOLLOUT) != 0) { | 279 if ((events & EPOLLOUT) != 0) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 302 EPOLLIN | EPOLLPRI | EPOLLOUT | EPOLLERR | EPOLLHUP | EPOLLRDHUP; | 292 EPOLLIN | EPOLLPRI | EPOLLOUT | EPOLLERR | EPOLLHUP | EPOLLRDHUP; |
| 303 if ((events & ~all_events) != 0) { | 293 if ((events & ~all_events) != 0) { |
| 304 Log::Print("(and %08x) ", events & ~all_events); | 294 Log::Print("(and %08x) ", events & ~all_events); |
| 305 } | 295 } |
| 306 Log::Print("(available %d) ", FDUtils::AvailableBytes(fd)); | 296 Log::Print("(available %d) ", FDUtils::AvailableBytes(fd)); |
| 307 | 297 |
| 308 Log::Print("\n"); | 298 Log::Print("\n"); |
| 309 } | 299 } |
| 310 #endif | 300 #endif |
| 311 | 301 |
| 312 | |
| 313 intptr_t EventHandlerImplementation::GetPollEvents(intptr_t events, | 302 intptr_t EventHandlerImplementation::GetPollEvents(intptr_t events, |
| 314 DescriptorInfo* di) { | 303 DescriptorInfo* di) { |
| 315 #ifdef DEBUG_POLL | 304 #ifdef DEBUG_POLL |
| 316 PrintEventMask(di->fd(), events); | 305 PrintEventMask(di->fd(), events); |
| 317 #endif | 306 #endif |
| 318 if ((events & EPOLLERR) != 0) { | 307 if ((events & EPOLLERR) != 0) { |
| 319 // Return error only if EPOLLIN is present. | 308 // Return error only if EPOLLIN is present. |
| 320 return ((events & EPOLLIN) != 0) ? (1 << kErrorEvent) : 0; | 309 return ((events & EPOLLIN) != 0) ? (1 << kErrorEvent) : 0; |
| 321 } | 310 } |
| 322 intptr_t event_mask = 0; | 311 intptr_t event_mask = 0; |
| 323 if ((events & EPOLLIN) != 0) { | 312 if ((events & EPOLLIN) != 0) { |
| 324 event_mask |= (1 << kInEvent); | 313 event_mask |= (1 << kInEvent); |
| 325 } | 314 } |
| 326 if ((events & EPOLLOUT) != 0) { | 315 if ((events & EPOLLOUT) != 0) { |
| 327 event_mask |= (1 << kOutEvent); | 316 event_mask |= (1 << kOutEvent); |
| 328 } | 317 } |
| 329 if ((events & (EPOLLHUP | EPOLLRDHUP)) != 0) { | 318 if ((events & (EPOLLHUP | EPOLLRDHUP)) != 0) { |
| 330 event_mask |= (1 << kCloseEvent); | 319 event_mask |= (1 << kCloseEvent); |
| 331 } | 320 } |
| 332 return event_mask; | 321 return event_mask; |
| 333 } | 322 } |
| 334 | 323 |
| 335 | |
| 336 void EventHandlerImplementation::HandleEvents(struct epoll_event* events, | 324 void EventHandlerImplementation::HandleEvents(struct epoll_event* events, |
| 337 int size) { | 325 int size) { |
| 338 bool interrupt_seen = false; | 326 bool interrupt_seen = false; |
| 339 for (int i = 0; i < size; i++) { | 327 for (int i = 0; i < size; i++) { |
| 340 if (events[i].data.ptr == NULL) { | 328 if (events[i].data.ptr == NULL) { |
| 341 interrupt_seen = true; | 329 interrupt_seen = true; |
| 342 } else { | 330 } else { |
| 343 DescriptorInfo* di = | 331 DescriptorInfo* di = |
| 344 reinterpret_cast<DescriptorInfo*>(events[i].data.ptr); | 332 reinterpret_cast<DescriptorInfo*>(events[i].data.ptr); |
| 345 const intptr_t old_mask = di->Mask(); | 333 const intptr_t old_mask = di->Mask(); |
| 346 const intptr_t event_mask = GetPollEvents(events[i].events, di); | 334 const intptr_t event_mask = GetPollEvents(events[i].events, di); |
| 347 if ((event_mask & (1 << kErrorEvent)) != 0) { | 335 if ((event_mask & (1 << kErrorEvent)) != 0) { |
| 348 di->NotifyAllDartPorts(event_mask); | 336 di->NotifyAllDartPorts(event_mask); |
| 349 UpdateEpollInstance(old_mask, di); | 337 UpdateEpollInstance(old_mask, di); |
| 350 } else if (event_mask != 0) { | 338 } else if (event_mask != 0) { |
| 351 Dart_Port port = di->NextNotifyDartPort(event_mask); | 339 Dart_Port port = di->NextNotifyDartPort(event_mask); |
| 352 ASSERT(port != 0); | 340 ASSERT(port != 0); |
| 353 UpdateEpollInstance(old_mask, di); | 341 UpdateEpollInstance(old_mask, di); |
| 354 DartUtils::PostInt32(port, event_mask); | 342 DartUtils::PostInt32(port, event_mask); |
| 355 } | 343 } |
| 356 } | 344 } |
| 357 } | 345 } |
| 358 if (interrupt_seen) { | 346 if (interrupt_seen) { |
| 359 // Handle after socket events, so we avoid closing a socket before we handle | 347 // Handle after socket events, so we avoid closing a socket before we handle |
| 360 // the current events. | 348 // the current events. |
| 361 HandleInterruptFd(); | 349 HandleInterruptFd(); |
| 362 } | 350 } |
| 363 } | 351 } |
| 364 | 352 |
| 365 | |
| 366 int64_t EventHandlerImplementation::GetTimeout() { | 353 int64_t EventHandlerImplementation::GetTimeout() { |
| 367 if (!timeout_queue_.HasTimeout()) { | 354 if (!timeout_queue_.HasTimeout()) { |
| 368 return kInfinityTimeout; | 355 return kInfinityTimeout; |
| 369 } | 356 } |
| 370 int64_t millis = | 357 int64_t millis = |
| 371 timeout_queue_.CurrentTimeout() - TimerUtils::GetCurrentMonotonicMillis(); | 358 timeout_queue_.CurrentTimeout() - TimerUtils::GetCurrentMonotonicMillis(); |
| 372 return (millis < 0) ? 0 : millis; | 359 return (millis < 0) ? 0 : millis; |
| 373 } | 360 } |
| 374 | 361 |
| 375 | |
| 376 void EventHandlerImplementation::HandleTimeout() { | 362 void EventHandlerImplementation::HandleTimeout() { |
| 377 if (timeout_queue_.HasTimeout()) { | 363 if (timeout_queue_.HasTimeout()) { |
| 378 int64_t millis = timeout_queue_.CurrentTimeout() - | 364 int64_t millis = timeout_queue_.CurrentTimeout() - |
| 379 TimerUtils::GetCurrentMonotonicMillis(); | 365 TimerUtils::GetCurrentMonotonicMillis(); |
| 380 if (millis <= 0) { | 366 if (millis <= 0) { |
| 381 DartUtils::PostNull(timeout_queue_.CurrentPort()); | 367 DartUtils::PostNull(timeout_queue_.CurrentPort()); |
| 382 timeout_queue_.RemoveCurrent(); | 368 timeout_queue_.RemoveCurrent(); |
| 383 } | 369 } |
| 384 } | 370 } |
| 385 } | 371 } |
| 386 | 372 |
| 387 | |
| 388 void EventHandlerImplementation::Poll(uword args) { | 373 void EventHandlerImplementation::Poll(uword args) { |
| 389 ThreadSignalBlocker signal_blocker(SIGPROF); | 374 ThreadSignalBlocker signal_blocker(SIGPROF); |
| 390 static const intptr_t kMaxEvents = 16; | 375 static const intptr_t kMaxEvents = 16; |
| 391 struct epoll_event events[kMaxEvents]; | 376 struct epoll_event events[kMaxEvents]; |
| 392 EventHandler* handler = reinterpret_cast<EventHandler*>(args); | 377 EventHandler* handler = reinterpret_cast<EventHandler*>(args); |
| 393 EventHandlerImplementation* handler_impl = &handler->delegate_; | 378 EventHandlerImplementation* handler_impl = &handler->delegate_; |
| 394 ASSERT(handler_impl != NULL); | 379 ASSERT(handler_impl != NULL); |
| 395 | 380 |
| 396 while (!handler_impl->shutdown_) { | 381 while (!handler_impl->shutdown_) { |
| 397 int64_t millis = handler_impl->GetTimeout(); | 382 int64_t millis = handler_impl->GetTimeout(); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 408 } | 393 } |
| 409 } else { | 394 } else { |
| 410 handler_impl->HandleTimeout(); | 395 handler_impl->HandleTimeout(); |
| 411 handler_impl->HandleEvents(events, result); | 396 handler_impl->HandleEvents(events, result); |
| 412 } | 397 } |
| 413 } | 398 } |
| 414 DEBUG_ASSERT(ReferenceCounted<Socket>::instances() == 0); | 399 DEBUG_ASSERT(ReferenceCounted<Socket>::instances() == 0); |
| 415 handler->NotifyShutdownDone(); | 400 handler->NotifyShutdownDone(); |
| 416 } | 401 } |
| 417 | 402 |
| 418 | |
| 419 void EventHandlerImplementation::Start(EventHandler* handler) { | 403 void EventHandlerImplementation::Start(EventHandler* handler) { |
| 420 int result = Thread::Start(&EventHandlerImplementation::Poll, | 404 int result = Thread::Start(&EventHandlerImplementation::Poll, |
| 421 reinterpret_cast<uword>(handler)); | 405 reinterpret_cast<uword>(handler)); |
| 422 if (result != 0) { | 406 if (result != 0) { |
| 423 FATAL1("Failed to start event handler thread %d", result); | 407 FATAL1("Failed to start event handler thread %d", result); |
| 424 } | 408 } |
| 425 } | 409 } |
| 426 | 410 |
| 427 | |
| 428 void EventHandlerImplementation::Shutdown() { | 411 void EventHandlerImplementation::Shutdown() { |
| 429 SendData(kShutdownId, 0, 0); | 412 SendData(kShutdownId, 0, 0); |
| 430 } | 413 } |
| 431 | 414 |
| 432 | |
| 433 void EventHandlerImplementation::SendData(intptr_t id, | 415 void EventHandlerImplementation::SendData(intptr_t id, |
| 434 Dart_Port dart_port, | 416 Dart_Port dart_port, |
| 435 int64_t data) { | 417 int64_t data) { |
| 436 WakeupHandler(id, dart_port, data); | 418 WakeupHandler(id, dart_port, data); |
| 437 } | 419 } |
| 438 | 420 |
| 439 | |
| 440 void* EventHandlerImplementation::GetHashmapKeyFromFd(intptr_t fd) { | 421 void* EventHandlerImplementation::GetHashmapKeyFromFd(intptr_t fd) { |
| 441 // The hashmap does not support keys with value 0. | 422 // The hashmap does not support keys with value 0. |
| 442 return reinterpret_cast<void*>(fd + 1); | 423 return reinterpret_cast<void*>(fd + 1); |
| 443 } | 424 } |
| 444 | 425 |
| 445 | |
| 446 uint32_t EventHandlerImplementation::GetHashmapHashFromFd(intptr_t fd) { | 426 uint32_t EventHandlerImplementation::GetHashmapHashFromFd(intptr_t fd) { |
| 447 // The hashmap does not support keys with value 0. | 427 // The hashmap does not support keys with value 0. |
| 448 return dart::Utils::WordHash(fd + 1); | 428 return dart::Utils::WordHash(fd + 1); |
| 449 } | 429 } |
| 450 | 430 |
| 451 } // namespace bin | 431 } // namespace bin |
| 452 } // namespace dart | 432 } // namespace dart |
| 453 | 433 |
| 454 #endif // defined(HOST_OS_ANDROID) | 434 #endif // defined(HOST_OS_ANDROID) |
| 455 | 435 |
| 456 #endif // !defined(DART_IO_DISABLED) | 436 #endif // !defined(DART_IO_DISABLED) |
| OLD | NEW |