Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(58)

Side by Side Diff: runtime/bin/eventhandler_android.cc

Issue 2760293002: [dart:io] Adds a finalizer to _NativeSocket to avoid socket leaks (Closed)
Patch Set: Address comments Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/bin/eventhandler.cc ('k') | runtime/bin/eventhandler_fuchsia.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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)
OLDNEW
« no previous file with comments | « runtime/bin/eventhandler.cc ('k') | runtime/bin/eventhandler_fuchsia.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698