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" |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 InterruptMessage msg[MAX_MESSAGES]; | 198 InterruptMessage msg[MAX_MESSAGES]; |
199 ssize_t bytes = TEMP_FAILURE_RETRY_NO_SIGNAL_BLOCKER( | 199 ssize_t bytes = TEMP_FAILURE_RETRY_NO_SIGNAL_BLOCKER( |
200 read(interrupt_fds_[0], msg, MAX_MESSAGES * kInterruptMessageSize)); | 200 read(interrupt_fds_[0], msg, MAX_MESSAGES * kInterruptMessageSize)); |
201 for (ssize_t i = 0; i < bytes / kInterruptMessageSize; i++) { | 201 for (ssize_t i = 0; i < bytes / kInterruptMessageSize; i++) { |
202 if (msg[i].id == kTimerId) { | 202 if (msg[i].id == kTimerId) { |
203 timeout_queue_.UpdateTimeout(msg[i].dart_port, msg[i].data); | 203 timeout_queue_.UpdateTimeout(msg[i].dart_port, msg[i].data); |
204 } else if (msg[i].id == kShutdownId) { | 204 } else if (msg[i].id == kShutdownId) { |
205 shutdown_ = true; | 205 shutdown_ = true; |
206 } else { | 206 } else { |
207 ASSERT((msg[i].data & COMMAND_MASK) != 0); | 207 ASSERT((msg[i].data & COMMAND_MASK) != 0); |
208 | 208 Socket* socket = reinterpret_cast<Socket*>(msg[i].id); |
| 209 RefCntReleaseScope<Socket> rs(socket); |
| 210 if (socket->fd() == -1) { |
| 211 continue; |
| 212 } |
209 DescriptorInfo* di = | 213 DescriptorInfo* di = |
210 GetDescriptorInfo(msg[i].id, IS_LISTENING_SOCKET(msg[i].data)); | 214 GetDescriptorInfo(socket->fd(), IS_LISTENING_SOCKET(msg[i].data)); |
211 if (IS_COMMAND(msg[i].data, kShutdownReadCommand)) { | 215 if (IS_COMMAND(msg[i].data, kShutdownReadCommand)) { |
212 ASSERT(!di->IsListeningSocket()); | 216 ASSERT(!di->IsListeningSocket()); |
213 // Close the socket for reading. | 217 // Close the socket for reading. |
214 VOID_NO_RETRY_EXPECTED(shutdown(di->fd(), SHUT_RD)); | 218 VOID_NO_RETRY_EXPECTED(shutdown(di->fd(), SHUT_RD)); |
215 } else if (IS_COMMAND(msg[i].data, kShutdownWriteCommand)) { | 219 } else if (IS_COMMAND(msg[i].data, kShutdownWriteCommand)) { |
216 ASSERT(!di->IsListeningSocket()); | 220 ASSERT(!di->IsListeningSocket()); |
217 // Close the socket for writing. | 221 // Close the socket for writing. |
218 VOID_NO_RETRY_EXPECTED(shutdown(di->fd(), SHUT_WR)); | 222 VOID_NO_RETRY_EXPECTED(shutdown(di->fd(), SHUT_WR)); |
219 } else if (IS_COMMAND(msg[i].data, kCloseCommand)) { | 223 } else if (IS_COMMAND(msg[i].data, kCloseCommand)) { |
220 // Close the socket and free system resources and move on to next | 224 // Close the socket and free system resources and move on to next |
221 // message. | 225 // message. |
222 intptr_t old_mask = di->Mask(); | 226 intptr_t old_mask = di->Mask(); |
223 Dart_Port port = msg[i].dart_port; | 227 Dart_Port port = msg[i].dart_port; |
224 di->RemovePort(port); | 228 di->RemovePort(port); |
225 intptr_t new_mask = di->Mask(); | 229 intptr_t new_mask = di->Mask(); |
226 UpdateEpollInstance(old_mask, di); | 230 UpdateEpollInstance(old_mask, di); |
227 | 231 |
228 intptr_t fd = di->fd(); | 232 intptr_t fd = di->fd(); |
229 if (di->IsListeningSocket()) { | 233 if (di->IsListeningSocket()) { |
230 // We only close the socket file descriptor from the operating | 234 // We only close the socket file descriptor from the operating |
231 // system if there are no other dart socket objects which | 235 // system if there are no other dart socket objects which |
232 // are listening on the same (address, port) combination. | 236 // are listening on the same (address, port) combination. |
233 ListeningSocketRegistry* registry = | 237 ListeningSocketRegistry* registry = |
234 ListeningSocketRegistry::Instance(); | 238 ListeningSocketRegistry::Instance(); |
235 | 239 |
236 MutexLocker locker(registry->mutex()); | 240 MutexLocker locker(registry->mutex()); |
237 | 241 |
238 if (registry->CloseSafe(fd)) { | 242 if (registry->CloseSafe(socket)) { |
239 ASSERT(new_mask == 0); | 243 ASSERT(new_mask == 0); |
240 socket_map_.Remove(GetHashmapKeyFromFd(fd), | 244 socket_map_.Remove(GetHashmapKeyFromFd(fd), |
241 GetHashmapHashFromFd(fd)); | 245 GetHashmapHashFromFd(fd)); |
242 di->Close(); | 246 di->Close(); |
243 delete di; | 247 delete di; |
| 248 socket->SetClosedFd(); |
244 } | 249 } |
245 } else { | 250 } else { |
246 ASSERT(new_mask == 0); | 251 ASSERT(new_mask == 0); |
247 socket_map_.Remove(GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd)); | 252 socket_map_.Remove(GetHashmapKeyFromFd(fd), GetHashmapHashFromFd(fd)); |
248 di->Close(); | 253 di->Close(); |
249 delete di; | 254 delete di; |
| 255 socket->SetClosedFd(); |
250 } | 256 } |
251 | 257 |
252 DartUtils::PostInt32(port, 1 << kDestroyedEvent); | 258 DartUtils::PostInt32(port, 1 << kDestroyedEvent); |
253 } else if (IS_COMMAND(msg[i].data, kReturnTokenCommand)) { | 259 } else if (IS_COMMAND(msg[i].data, kReturnTokenCommand)) { |
254 int count = TOKEN_COUNT(msg[i].data); | 260 int count = TOKEN_COUNT(msg[i].data); |
255 intptr_t old_mask = di->Mask(); | 261 intptr_t old_mask = di->Mask(); |
256 di->ReturnTokens(msg[i].dart_port, count); | 262 di->ReturnTokens(msg[i].dart_port, count); |
257 UpdateEpollInstance(old_mask, di); | 263 UpdateEpollInstance(old_mask, di); |
258 } else if (IS_COMMAND(msg[i].data, kSetEventMaskCommand)) { | 264 } else if (IS_COMMAND(msg[i].data, kSetEventMaskCommand)) { |
259 // `events` can only have kInEvent/kOutEvent flags set. | 265 // `events` can only have kInEvent/kOutEvent flags set. |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
398 ASSERT(EAGAIN == EWOULDBLOCK); | 404 ASSERT(EAGAIN == EWOULDBLOCK); |
399 if (result == -1) { | 405 if (result == -1) { |
400 if (errno != EWOULDBLOCK) { | 406 if (errno != EWOULDBLOCK) { |
401 perror("Poll failed"); | 407 perror("Poll failed"); |
402 } | 408 } |
403 } else { | 409 } else { |
404 handler_impl->HandleTimeout(); | 410 handler_impl->HandleTimeout(); |
405 handler_impl->HandleEvents(events, result); | 411 handler_impl->HandleEvents(events, result); |
406 } | 412 } |
407 } | 413 } |
| 414 DEBUG_ASSERT(ReferenceCounted<Socket>::instances() == 0); |
408 handler->NotifyShutdownDone(); | 415 handler->NotifyShutdownDone(); |
409 } | 416 } |
410 | 417 |
411 | 418 |
412 void EventHandlerImplementation::Start(EventHandler* handler) { | 419 void EventHandlerImplementation::Start(EventHandler* handler) { |
413 int result = Thread::Start(&EventHandlerImplementation::Poll, | 420 int result = Thread::Start(&EventHandlerImplementation::Poll, |
414 reinterpret_cast<uword>(handler)); | 421 reinterpret_cast<uword>(handler)); |
415 if (result != 0) { | 422 if (result != 0) { |
416 FATAL1("Failed to start event handler thread %d", result); | 423 FATAL1("Failed to start event handler thread %d", result); |
417 } | 424 } |
(...skipping 22 matching lines...) Expand all Loading... |
440 // The hashmap does not support keys with value 0. | 447 // The hashmap does not support keys with value 0. |
441 return dart::Utils::WordHash(fd + 1); | 448 return dart::Utils::WordHash(fd + 1); |
442 } | 449 } |
443 | 450 |
444 } // namespace bin | 451 } // namespace bin |
445 } // namespace dart | 452 } // namespace dart |
446 | 453 |
447 #endif // defined(HOST_OS_ANDROID) | 454 #endif // defined(HOST_OS_ANDROID) |
448 | 455 |
449 #endif // !defined(DART_IO_DISABLED) | 456 #endif // !defined(DART_IO_DISABLED) |
OLD | NEW |