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 | 9 |
10 #include <errno.h> // NOLINT | 10 #include <errno.h> // NOLINT |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 EPOLL_CTL_ADD, | 106 EPOLL_CTL_ADD, |
107 interrupt_fds_[0], | 107 interrupt_fds_[0], |
108 &event)); | 108 &event)); |
109 if (status == -1) { | 109 if (status == -1) { |
110 FATAL("Failed adding interrupt fd to epoll instance"); | 110 FATAL("Failed adding interrupt fd to epoll instance"); |
111 } | 111 } |
112 } | 112 } |
113 | 113 |
114 | 114 |
115 EventHandlerImplementation::~EventHandlerImplementation() { | 115 EventHandlerImplementation::~EventHandlerImplementation() { |
| 116 VOID_TEMP_FAILURE_RETRY(close(epoll_fd_)); |
116 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[0])); | 117 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[0])); |
117 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[1])); | 118 VOID_TEMP_FAILURE_RETRY(close(interrupt_fds_[1])); |
118 } | 119 } |
119 | 120 |
120 | 121 |
121 SocketData* EventHandlerImplementation::GetSocketData(intptr_t fd) { | 122 SocketData* EventHandlerImplementation::GetSocketData( |
| 123 intptr_t fd, bool listening_socket) { |
122 ASSERT(fd >= 0); | 124 ASSERT(fd >= 0); |
123 HashMap::Entry* entry = socket_map_.Lookup( | 125 HashMap::Entry* entry = socket_map_.Lookup( |
124 GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd), true); | 126 GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd), true); |
125 ASSERT(entry != NULL); | 127 ASSERT(entry != NULL); |
126 SocketData* sd = reinterpret_cast<SocketData*>(entry->value); | 128 SocketData* sd = reinterpret_cast<SocketData*>(entry->value); |
127 if (sd == NULL) { | 129 if (sd == NULL) { |
128 // If there is no data in the hash map for this file descriptor a | 130 // If there is no data in the hash map for this file descriptor a |
129 // new SocketData for the file descriptor is inserted. | 131 // new SocketData for the file descriptor is inserted. |
130 sd = new SocketData(fd); | 132 sd = new SocketData(fd, listening_socket); |
131 entry->value = sd; | 133 entry->value = sd; |
132 } | 134 } |
133 ASSERT(fd == sd->fd()); | 135 ASSERT(fd == sd->fd()); |
134 return sd; | 136 return sd; |
135 } | 137 } |
136 | 138 |
137 | 139 |
138 void EventHandlerImplementation::WakeupHandler(intptr_t id, | 140 void EventHandlerImplementation::WakeupHandler(intptr_t id, |
139 Dart_Port dart_port, | 141 Dart_Port dart_port, |
140 int64_t data) { | 142 int64_t data) { |
(...skipping 20 matching lines...) Expand all Loading... |
161 const intptr_t MAX_MESSAGES = kInterruptMessageSize; | 163 const intptr_t MAX_MESSAGES = kInterruptMessageSize; |
162 InterruptMessage msg[MAX_MESSAGES]; | 164 InterruptMessage msg[MAX_MESSAGES]; |
163 ssize_t bytes = TEMP_FAILURE_RETRY_NO_SIGNAL_BLOCKER( | 165 ssize_t bytes = TEMP_FAILURE_RETRY_NO_SIGNAL_BLOCKER( |
164 read(interrupt_fds_[0], msg, MAX_MESSAGES * kInterruptMessageSize)); | 166 read(interrupt_fds_[0], msg, MAX_MESSAGES * kInterruptMessageSize)); |
165 for (ssize_t i = 0; i < bytes / kInterruptMessageSize; i++) { | 167 for (ssize_t i = 0; i < bytes / kInterruptMessageSize; i++) { |
166 if (msg[i].id == kTimerId) { | 168 if (msg[i].id == kTimerId) { |
167 timeout_queue_.UpdateTimeout(msg[i].dart_port, msg[i].data); | 169 timeout_queue_.UpdateTimeout(msg[i].dart_port, msg[i].data); |
168 } else if (msg[i].id == kShutdownId) { | 170 } else if (msg[i].id == kShutdownId) { |
169 shutdown_ = true; | 171 shutdown_ = true; |
170 } else { | 172 } else { |
171 SocketData* sd = GetSocketData(msg[i].id); | 173 ASSERT((msg[i].data & COMMAND_MASK) != 0); |
172 | 174 |
| 175 SocketData* sd = GetSocketData( |
| 176 msg[i].id, IS_LISTENING_SOCKET(msg[i].data)); |
173 if (IS_COMMAND(msg[i].data, kShutdownReadCommand)) { | 177 if (IS_COMMAND(msg[i].data, kShutdownReadCommand)) { |
174 // Close the socket for reading. | 178 // Close the socket for reading. |
175 shutdown(sd->fd(), SHUT_RD); | 179 shutdown(sd->fd(), SHUT_RD); |
176 } else if (IS_COMMAND(msg[i].data, kShutdownWriteCommand)) { | 180 } else if (IS_COMMAND(msg[i].data, kShutdownWriteCommand)) { |
177 // Close the socket for writing. | 181 // Close the socket for writing. |
178 shutdown(sd->fd(), SHUT_WR); | 182 shutdown(sd->fd(), SHUT_WR); |
179 } else if (IS_COMMAND(msg[i].data, kCloseCommand)) { | 183 } else if (IS_COMMAND(msg[i].data, kCloseCommand)) { |
180 // Close the socket and free system resources and move on to | 184 // Close the socket and free system resources and move on to |
181 // next message. | 185 // next message. |
182 RemoveFromEpollInstance(epoll_fd_, sd); | 186 RemoveFromEpollInstance(epoll_fd_, sd); |
183 intptr_t fd = sd->fd(); | 187 intptr_t fd = sd->fd(); |
184 sd->Close(); | 188 sd->Close(); |
185 socket_map_.Remove(GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd)); | 189 socket_map_.Remove(GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd)); |
186 delete sd; | 190 delete sd; |
187 DartUtils::PostInt32(msg[i].dart_port, 1 << kDestroyedEvent); | 191 DartUtils::PostInt32(msg[i].dart_port, 1 << kDestroyedEvent); |
188 } else if (IS_COMMAND(msg[i].data, kReturnTokenCommand)) { | 192 } else if (IS_COMMAND(msg[i].data, kReturnTokenCommand)) { |
189 int count = TOKEN_COUNT(msg[i].data); | 193 int count = TOKEN_COUNT(msg[i].data); |
190 | 194 |
191 for (int i = 0; i < count; i++) { | 195 for (int i = 0; i < count; i++) { |
192 if (sd->ReturnToken()) { | 196 if (sd->ReturnToken()) { |
193 AddToEpollInstance(epoll_fd_, sd); | 197 AddToEpollInstance(epoll_fd_, sd); |
194 } | 198 } |
195 } | 199 } |
| 200 } else if (IS_COMMAND(msg[i].data, kSetEventMaskCommand)) { |
| 201 // `events` can only have kInEvent/kOutEvent flags set. |
| 202 intptr_t events = msg[i].data & EVENT_MASK; |
| 203 ASSERT(0 == (events & ~(1 << kInEvent | 1 << kOutEvent))); |
| 204 |
| 205 // Setup events to wait for. |
| 206 sd->SetPortAndMask(msg[i].dart_port, events); |
| 207 AddToEpollInstance(epoll_fd_, sd); |
196 } else { | 208 } else { |
197 ASSERT_NO_COMMAND(msg[i].data); | 209 UNREACHABLE(); |
198 // Setup events to wait for. | |
199 sd->SetPortAndMask(msg[i].dart_port, msg[i].data); | |
200 AddToEpollInstance(epoll_fd_, sd); | |
201 } | 210 } |
202 } | 211 } |
203 } | 212 } |
204 } | 213 } |
205 | 214 |
206 #ifdef DEBUG_POLL | 215 #ifdef DEBUG_POLL |
207 static void PrintEventMask(intptr_t fd, intptr_t events) { | 216 static void PrintEventMask(intptr_t fd, intptr_t events) { |
208 Log::Print("%d ", fd); | 217 Log::Print("%d ", fd); |
209 if ((events & EPOLLIN) != 0) Log::Print("EPOLLIN "); | 218 if ((events & EPOLLIN) != 0) Log::Print("EPOLLIN "); |
210 if ((events & EPOLLPRI) != 0) Log::Print("EPOLLPRI "); | 219 if ((events & EPOLLPRI) != 0) Log::Print("EPOLLPRI "); |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
347 | 356 |
348 uint32_t EventHandlerImplementation::GetHashmapHashFromFd(intptr_t fd) { | 357 uint32_t EventHandlerImplementation::GetHashmapHashFromFd(intptr_t fd) { |
349 // The hashmap does not support keys with value 0. | 358 // The hashmap does not support keys with value 0. |
350 return dart::Utils::WordHash(fd + 1); | 359 return dart::Utils::WordHash(fd + 1); |
351 } | 360 } |
352 | 361 |
353 } // namespace bin | 362 } // namespace bin |
354 } // namespace dart | 363 } // namespace dart |
355 | 364 |
356 #endif // defined(TARGET_OS_ANDROID) | 365 #endif // defined(TARGET_OS_ANDROID) |
OLD | NEW |