| 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 "bin/eventhandler.h" | 5 #include "bin/eventhandler.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <pthread.h> | 8 #include <pthread.h> |
| 9 #include <stdio.h> | 9 #include <stdio.h> |
| 10 #include <string.h> | 10 #include <string.h> |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 UNREACHABLE(); | 26 UNREACHABLE(); |
| 27 return 0; | 27 return 0; |
| 28 } | 28 } |
| 29 return ((static_cast<int64_t>(tv.tv_sec) * 1000000) + tv.tv_usec) / 1000; | 29 return ((static_cast<int64_t>(tv.tv_sec) * 1000000) + tv.tv_usec) / 1000; |
| 30 } | 30 } |
| 31 | 31 |
| 32 | 32 |
| 33 static const int kInterruptMessageSize = sizeof(InterruptMessage); | 33 static const int kInterruptMessageSize = sizeof(InterruptMessage); |
| 34 static const int kInfinityTimeout = -1; | 34 static const int kInfinityTimeout = -1; |
| 35 static const int kTimerId = -1; | 35 static const int kTimerId = -1; |
| 36 static const int kShutdownId = -2; |
| 36 | 37 |
| 37 | 38 |
| 38 intptr_t SocketData::GetPollEvents() { | 39 intptr_t SocketData::GetPollEvents() { |
| 39 // Do not ask for EPOLLERR and EPOLLHUP explicitly as they are | 40 // Do not ask for EPOLLERR and EPOLLHUP explicitly as they are |
| 40 // triggered anyway. | 41 // triggered anyway. |
| 41 intptr_t events = 0; | 42 intptr_t events = 0; |
| 42 if (!IsClosedRead()) { | 43 if (!IsClosedRead()) { |
| 43 if ((mask_ & (1 << kInEvent)) != 0) { | 44 if ((mask_ & (1 << kInEvent)) != 0) { |
| 44 events |= EPOLLIN; | 45 events |= EPOLLIN; |
| 45 } | 46 } |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 98 EventHandlerImplementation::EventHandlerImplementation() | 99 EventHandlerImplementation::EventHandlerImplementation() |
| 99 : socket_map_(&HashMap::SamePointerValue, 16) { | 100 : socket_map_(&HashMap::SamePointerValue, 16) { |
| 100 intptr_t result; | 101 intptr_t result; |
| 101 result = TEMP_FAILURE_RETRY(pipe(interrupt_fds_)); | 102 result = TEMP_FAILURE_RETRY(pipe(interrupt_fds_)); |
| 102 if (result != 0) { | 103 if (result != 0) { |
| 103 FATAL("Pipe creation failed"); | 104 FATAL("Pipe creation failed"); |
| 104 } | 105 } |
| 105 FDUtils::SetNonBlocking(interrupt_fds_[0]); | 106 FDUtils::SetNonBlocking(interrupt_fds_[0]); |
| 106 timeout_ = kInfinityTimeout; | 107 timeout_ = kInfinityTimeout; |
| 107 timeout_port_ = 0; | 108 timeout_port_ = 0; |
| 109 shutdown_ = false; |
| 108 // The initial size passed to epoll_create is ignore on newer (>= | 110 // The initial size passed to epoll_create is ignore on newer (>= |
| 109 // 2.6.8) Linux versions | 111 // 2.6.8) Linux versions |
| 110 static const int kEpollInitialSize = 64; | 112 static const int kEpollInitialSize = 64; |
| 111 epoll_fd_ = TEMP_FAILURE_RETRY(epoll_create(kEpollInitialSize)); | 113 epoll_fd_ = TEMP_FAILURE_RETRY(epoll_create(kEpollInitialSize)); |
| 112 if (epoll_fd_ == -1) { | 114 if (epoll_fd_ == -1) { |
| 113 FATAL("Failed creating epoll file descriptor"); | 115 FATAL("Failed creating epoll file descriptor"); |
| 114 } | 116 } |
| 115 // Register the interrupt_fd with the epoll instance. | 117 // Register the interrupt_fd with the epoll instance. |
| 116 struct epoll_event event; | 118 struct epoll_event event; |
| 117 event.events = EPOLLIN; | 119 event.events = EPOLLIN; |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 } | 188 } |
| 187 return (total_read == kInterruptMessageSize) ? true : false; | 189 return (total_read == kInterruptMessageSize) ? true : false; |
| 188 } | 190 } |
| 189 | 191 |
| 190 void EventHandlerImplementation::HandleInterruptFd() { | 192 void EventHandlerImplementation::HandleInterruptFd() { |
| 191 InterruptMessage msg; | 193 InterruptMessage msg; |
| 192 while (GetInterruptMessage(&msg)) { | 194 while (GetInterruptMessage(&msg)) { |
| 193 if (msg.id == kTimerId) { | 195 if (msg.id == kTimerId) { |
| 194 timeout_ = msg.data; | 196 timeout_ = msg.data; |
| 195 timeout_port_ = msg.dart_port; | 197 timeout_port_ = msg.dart_port; |
| 198 } else if (msg.id == kShutdownId) { |
| 199 shutdown_ = true; |
| 196 } else { | 200 } else { |
| 197 SocketData* sd = GetSocketData(msg.id); | 201 SocketData* sd = GetSocketData(msg.id); |
| 198 if ((msg.data & (1 << kShutdownReadCommand)) != 0) { | 202 if ((msg.data & (1 << kShutdownReadCommand)) != 0) { |
| 199 ASSERT(msg.data == (1 << kShutdownReadCommand)); | 203 ASSERT(msg.data == (1 << kShutdownReadCommand)); |
| 200 // Close the socket for reading. | 204 // Close the socket for reading. |
| 201 sd->ShutdownRead(); | 205 sd->ShutdownRead(); |
| 202 UpdateEpollInstance(epoll_fd_, sd); | 206 UpdateEpollInstance(epoll_fd_, sd); |
| 203 } else if ((msg.data & (1 << kShutdownWriteCommand)) != 0) { | 207 } else if ((msg.data & (1 << kShutdownWriteCommand)) != 0) { |
| 204 ASSERT(msg.data == (1 << kShutdownWriteCommand)); | 208 ASSERT(msg.data == (1 << kShutdownWriteCommand)); |
| 205 // Close the socket for writing. | 209 // Close the socket for writing. |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 366 } | 370 } |
| 367 } | 371 } |
| 368 | 372 |
| 369 | 373 |
| 370 void EventHandlerImplementation::Poll(uword args) { | 374 void EventHandlerImplementation::Poll(uword args) { |
| 371 static const intptr_t kMaxEvents = 16; | 375 static const intptr_t kMaxEvents = 16; |
| 372 struct epoll_event events[kMaxEvents]; | 376 struct epoll_event events[kMaxEvents]; |
| 373 EventHandlerImplementation* handler = | 377 EventHandlerImplementation* handler = |
| 374 reinterpret_cast<EventHandlerImplementation*>(args); | 378 reinterpret_cast<EventHandlerImplementation*>(args); |
| 375 ASSERT(handler != NULL); | 379 ASSERT(handler != NULL); |
| 376 while (1) { | 380 while (!handler->shutdown_) { |
| 377 intptr_t millis = handler->GetTimeout(); | 381 intptr_t millis = handler->GetTimeout(); |
| 378 intptr_t result = TEMP_FAILURE_RETRY(epoll_wait(handler->epoll_fd_, | 382 intptr_t result = TEMP_FAILURE_RETRY(epoll_wait(handler->epoll_fd_, |
| 379 events, | 383 events, |
| 380 kMaxEvents, | 384 kMaxEvents, |
| 381 millis)); | 385 millis)); |
| 382 ASSERT(EAGAIN == EWOULDBLOCK); | 386 ASSERT(EAGAIN == EWOULDBLOCK); |
| 383 if (result == -1) { | 387 if (result == -1) { |
| 384 if (errno != EWOULDBLOCK) { | 388 if (errno != EWOULDBLOCK) { |
| 385 perror("Poll failed"); | 389 perror("Poll failed"); |
| 386 } | 390 } |
| 387 } else { | 391 } else { |
| 388 handler->HandleTimeout(); | 392 handler->HandleTimeout(); |
| 389 handler->HandleEvents(events, result); | 393 handler->HandleEvents(events, result); |
| 390 } | 394 } |
| 391 } | 395 } |
| 392 } | 396 } |
| 393 | 397 |
| 394 | 398 |
| 395 void EventHandlerImplementation::StartEventHandler() { | 399 void EventHandlerImplementation::Start() { |
| 396 int result = dart::Thread::Start(&EventHandlerImplementation::Poll, | 400 int result = dart::Thread::Start(&EventHandlerImplementation::Poll, |
| 397 reinterpret_cast<uword>(this)); | 401 reinterpret_cast<uword>(this)); |
| 398 if (result != 0) { | 402 if (result != 0) { |
| 399 FATAL1("Failed to start event handler thread %d", result); | 403 FATAL1("Failed to start event handler thread %d", result); |
| 400 } | 404 } |
| 401 } | 405 } |
| 402 | 406 |
| 403 | 407 |
| 408 void EventHandlerImplementation::Shutdown() { |
| 409 SendData(kShutdownId, 0, 0); |
| 410 } |
| 411 |
| 412 |
| 404 void EventHandlerImplementation::SendData(intptr_t id, | 413 void EventHandlerImplementation::SendData(intptr_t id, |
| 405 Dart_Port dart_port, | 414 Dart_Port dart_port, |
| 406 intptr_t data) { | 415 intptr_t data) { |
| 407 WakeupHandler(id, dart_port, data); | 416 WakeupHandler(id, dart_port, data); |
| 408 } | 417 } |
| 409 | 418 |
| 410 | 419 |
| 411 void* EventHandlerImplementation::GetHashmapKeyFromFd(intptr_t fd) { | 420 void* EventHandlerImplementation::GetHashmapKeyFromFd(intptr_t fd) { |
| 412 // The hashmap does not support keys with value 0. | 421 // The hashmap does not support keys with value 0. |
| 413 return reinterpret_cast<void*>(fd + 1); | 422 return reinterpret_cast<void*>(fd + 1); |
| 414 } | 423 } |
| 415 | 424 |
| 416 | 425 |
| 417 uint32_t EventHandlerImplementation::GetHashmapHashFromFd(intptr_t fd) { | 426 uint32_t EventHandlerImplementation::GetHashmapHashFromFd(intptr_t fd) { |
| 418 // The hashmap does not support keys with value 0. | 427 // The hashmap does not support keys with value 0. |
| 419 return dart::Utils::WordHash(fd + 1); | 428 return dart::Utils::WordHash(fd + 1); |
| 420 } | 429 } |
| OLD | NEW |