| OLD | NEW |
| 1 // Copyright (c) 2015, the Fletch project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Fletch 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.md file. | 3 // BSD-style license that can be found in the LICENSE.md file. |
| 4 | 4 |
| 5 #if defined(FLETCH_TARGET_OS_LINUX) | 5 #if defined(FLETCH_TARGET_OS_LINUX) |
| 6 | 6 |
| 7 #include "src/vm/event_handler.h" | 7 #include "src/vm/event_handler.h" |
| 8 | 8 |
| 9 #include <sys/epoll.h> | 9 #include <sys/epoll.h> |
| 10 #include <sys/types.h> | 10 #include <sys/types.h> |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 | 24 |
| 25 int EventHandler::Create() { | 25 int EventHandler::Create() { |
| 26 int fd = epoll_create(1); | 26 int fd = epoll_create(1); |
| 27 int status = fcntl(fd, F_SETFD, FD_CLOEXEC); | 27 int status = fcntl(fd, F_SETFD, FD_CLOEXEC); |
| 28 if (status == -1) FATAL("Failed making epoll descriptor close on exec."); | 28 if (status == -1) FATAL("Failed making epoll descriptor close on exec."); |
| 29 return fd; | 29 return fd; |
| 30 } | 30 } |
| 31 | 31 |
| 32 void EventHandler::Run() { | 32 void EventHandler::Run() { |
| 33 struct epoll_event event; | 33 struct epoll_event event; |
| 34 event.events = EPOLLHUP | EPOLLRDHUP; | 34 event.events = EPOLLHUP | EPOLLRDHUP | EPOLLIN; |
| 35 event.data.fd = read_fd_; | 35 event.data.fd = read_fd_; |
| 36 epoll_ctl(fd_, EPOLL_CTL_ADD, read_fd_, &event); | 36 epoll_ctl(fd_, EPOLL_CTL_ADD, read_fd_, &event); |
| 37 while (true) { | 37 while (true) { |
| 38 int status = epoll_wait(fd_, &event, 1, -1); | 38 int64 next_timeout; |
| 39 { |
| 40 ScopedMonitorLock locker(monitor_); |
| 41 next_timeout = next_timeout_; |
| 42 } |
| 43 |
| 44 if (next_timeout == INT64_MAX) { |
| 45 next_timeout = -1; |
| 46 } else { |
| 47 next_timeout -= Platform::GetMicroseconds() / 1000; |
| 48 if (next_timeout < 0) next_timeout = 0; |
| 49 } |
| 50 |
| 51 int status = epoll_wait(fd_, &event, 1, next_timeout); |
| 52 |
| 53 HandleTimeouts(); |
| 54 |
| 39 if (status != 1) continue; | 55 if (status != 1) continue; |
| 40 | 56 |
| 57 int events = event.events; |
| 58 |
| 41 if (event.data.fd == read_fd_) { | 59 if (event.data.fd == read_fd_) { |
| 42 close(read_fd_); | 60 if ((events & EPOLLIN) != 0) { |
| 43 close(fd_); | 61 char b; |
| 62 read(read_fd_, &b, 1); |
| 63 continue; |
| 64 } else { |
| 65 close(read_fd_); |
| 66 close(fd_); |
| 44 | 67 |
| 45 ScopedMonitorLock locker(monitor_); | 68 ScopedMonitorLock locker(monitor_); |
| 46 fd_ = -1; | 69 fd_ = -1; |
| 47 monitor_->Notify(); | 70 monitor_->Notify(); |
| 48 return; | 71 return; |
| 72 } |
| 49 } | 73 } |
| 50 | 74 |
| 51 int events = event.events; | |
| 52 word mask = 0; | 75 word mask = 0; |
| 53 if ((events & EPOLLIN) != 0) mask |= READ_EVENT; | 76 if ((events & EPOLLIN) != 0) mask |= READ_EVENT; |
| 54 if ((events & EPOLLOUT) != 0) mask |= WRITE_EVENT; | 77 if ((events & EPOLLOUT) != 0) mask |= WRITE_EVENT; |
| 55 if ((events & EPOLLRDHUP) != 0) mask |= CLOSE_EVENT; | 78 if ((events & EPOLLRDHUP) != 0) mask |= CLOSE_EVENT; |
| 56 if ((events & EPOLLHUP) != 0) mask |= CLOSE_EVENT; | 79 if ((events & EPOLLHUP) != 0) mask |= CLOSE_EVENT; |
| 57 if ((events & EPOLLERR) != 0) mask |= ERROR_EVENT; | 80 if ((events & EPOLLERR) != 0) mask |= ERROR_EVENT; |
| 58 | 81 |
| 59 Port* port = reinterpret_cast<Port*>(event.data.ptr); | 82 Port* port = reinterpret_cast<Port*>(event.data.ptr); |
| 60 Send(port, mask); | 83 Send(port, mask); |
| 61 } | 84 } |
| 62 } | 85 } |
| 63 | 86 |
| 64 } // namespace fletch | 87 } // namespace fletch |
| 65 | 88 |
| 66 #endif // defined(FLETCH_TARGET_OS_LINUX) | 89 #endif // defined(FLETCH_TARGET_OS_LINUX) |
| OLD | NEW |