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

Side by Side Diff: runtime/bin/socket_win.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/socket_macos.cc ('k') | tests/standalone/io/socket_bind_test.dart » ('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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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_WINDOWS) 8 #if defined(HOST_OS_WINDOWS)
9 9
10 #include "bin/socket.h" 10 #include "bin/socket.h"
(...skipping 28 matching lines...) Expand all
39 39
40 40
41 bool Socket::FormatNumericAddress(const RawAddr& addr, char* address, int len) { 41 bool Socket::FormatNumericAddress(const RawAddr& addr, char* address, int len) {
42 socklen_t salen = SocketAddress::GetAddrLength(addr); 42 socklen_t salen = SocketAddress::GetAddrLength(addr);
43 DWORD l = len; 43 DWORD l = len;
44 RawAddr& raw = const_cast<RawAddr&>(addr); 44 RawAddr& raw = const_cast<RawAddr&>(addr);
45 return WSAAddressToStringA(&raw.addr, salen, NULL, address, &l) != 0; 45 return WSAAddressToStringA(&raw.addr, salen, NULL, address, &l) != 0;
46 } 46 }
47 47
48 48
49 Socket::Socket(intptr_t fd) : ReferenceCounted(), fd_(fd), port_(ILLEGAL_PORT) {
50 ASSERT(fd_ != kClosedFd);
51 Handle* handle = reinterpret_cast<Handle*>(fd_);
52 ASSERT(handle != NULL);
53 }
54
55
56 void Socket::SetClosedFd() {
57 ASSERT(fd_ != kClosedFd);
58 Handle* handle = reinterpret_cast<Handle*>(fd_);
59 ASSERT(handle != NULL);
60 handle->Release();
61 fd_ = kClosedFd;
62 }
63
64
49 static Mutex* init_mutex = new Mutex(); 65 static Mutex* init_mutex = new Mutex();
50 static bool socket_initialized = false; 66 static bool socket_initialized = false;
51 67
52 bool Socket::Initialize() { 68 bool Socket::Initialize() {
53 MutexLocker lock(init_mutex); 69 MutexLocker lock(init_mutex);
54 if (socket_initialized) { 70 if (socket_initialized) {
55 return true; 71 return true;
56 } 72 }
57 int err; 73 int err;
58 WSADATA winsock_data; 74 WSADATA winsock_data;
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 const RawAddr& bind_addr) { 174 const RawAddr& bind_addr) {
159 ASSERT(reinterpret_cast<Handle*>(fd)->is_client_socket()); 175 ASSERT(reinterpret_cast<Handle*>(fd)->is_client_socket());
160 ClientSocket* handle = reinterpret_cast<ClientSocket*>(fd); 176 ClientSocket* handle = reinterpret_cast<ClientSocket*>(fd);
161 SOCKET s = handle->socket(); 177 SOCKET s = handle->socket();
162 178
163 int status = 179 int status =
164 bind(s, &bind_addr.addr, SocketAddress::GetAddrLength(bind_addr)); 180 bind(s, &bind_addr.addr, SocketAddress::GetAddrLength(bind_addr));
165 if (status != NO_ERROR) { 181 if (status != NO_ERROR) {
166 int rc = WSAGetLastError(); 182 int rc = WSAGetLastError();
167 handle->mark_closed(); // Destructor asserts that socket is marked closed. 183 handle->mark_closed(); // Destructor asserts that socket is marked closed.
168 delete handle; 184 handle->Release();
169 closesocket(s); 185 closesocket(s);
170 SetLastError(rc); 186 SetLastError(rc);
171 return -1; 187 return -1;
172 } 188 }
173 189
174 LPFN_CONNECTEX connectEx = NULL; 190 LPFN_CONNECTEX connectEx = NULL;
175 GUID guid_connect_ex = WSAID_CONNECTEX; 191 GUID guid_connect_ex = WSAID_CONNECTEX;
176 DWORD bytes; 192 DWORD bytes;
177 status = WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &guid_connect_ex, 193 status = WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &guid_connect_ex,
178 sizeof(guid_connect_ex), &connectEx, sizeof(connectEx), 194 sizeof(guid_connect_ex), &connectEx, sizeof(connectEx),
(...skipping 10 matching lines...) Expand all
189 205
190 if (status == TRUE) { 206 if (status == TRUE) {
191 handle->ConnectComplete(overlapped); 207 handle->ConnectComplete(overlapped);
192 return fd; 208 return fd;
193 } else if (WSAGetLastError() == ERROR_IO_PENDING) { 209 } else if (WSAGetLastError() == ERROR_IO_PENDING) {
194 return fd; 210 return fd;
195 } 211 }
196 rc = WSAGetLastError(); 212 rc = WSAGetLastError();
197 // Cleanup in case of error. 213 // Cleanup in case of error.
198 OverlappedBuffer::DisposeBuffer(overlapped); 214 OverlappedBuffer::DisposeBuffer(overlapped);
215 handle->Release();
199 } else { 216 } else {
200 rc = WSAGetLastError(); 217 rc = WSAGetLastError();
201 } 218 }
202 handle->Close(); 219 handle->Close();
203 delete handle; 220 handle->Release();
204 SetLastError(rc); 221 SetLastError(rc);
205 return -1; 222 return -1;
206 } 223 }
207 224
208 225
209 intptr_t Socket::CreateConnect(const RawAddr& addr) { 226 intptr_t Socket::CreateConnect(const RawAddr& addr) {
210 intptr_t fd = Create(addr); 227 intptr_t fd = Create(addr);
211 if (fd < 0) { 228 if (fd < 0) {
212 return fd; 229 return fd;
213 } 230 }
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
490 ListenSocket* listen_socket = new ListenSocket(s); 507 ListenSocket* listen_socket = new ListenSocket(s);
491 508
492 // Test for invalid socket port 65535 (some browsers disallow it). 509 // Test for invalid socket port 65535 (some browsers disallow it).
493 if ((SocketAddress::GetAddrPort(addr) == 0) && 510 if ((SocketAddress::GetAddrPort(addr) == 0) &&
494 (Socket::GetPort(reinterpret_cast<intptr_t>(listen_socket)) == 65535)) { 511 (Socket::GetPort(reinterpret_cast<intptr_t>(listen_socket)) == 65535)) {
495 // Don't close fd until we have created new. By doing that we ensure another 512 // Don't close fd until we have created new. By doing that we ensure another
496 // port. 513 // port.
497 intptr_t new_s = CreateBindListen(addr, backlog, v6_only); 514 intptr_t new_s = CreateBindListen(addr, backlog, v6_only);
498 DWORD rc = WSAGetLastError(); 515 DWORD rc = WSAGetLastError();
499 closesocket(s); 516 closesocket(s);
500 delete listen_socket; 517 listen_socket->Release();
501 SetLastError(rc); 518 SetLastError(rc);
502 return new_s; 519 return new_s;
503 } 520 }
504 521
505 status = listen(s, backlog > 0 ? backlog : SOMAXCONN); 522 status = listen(s, backlog > 0 ? backlog : SOMAXCONN);
506 if (status == SOCKET_ERROR) { 523 if (status == SOCKET_ERROR) {
507 DWORD rc = WSAGetLastError(); 524 DWORD rc = WSAGetLastError();
508 closesocket(s); 525 closesocket(s);
509 delete listen_socket; 526 listen_socket->Release();
510 SetLastError(rc); 527 SetLastError(rc);
511 return -1; 528 return -1;
512 } 529 }
513 530
514 return reinterpret_cast<intptr_t>(listen_socket); 531 return reinterpret_cast<intptr_t>(listen_socket);
515 } 532 }
516 533
517 534
518 bool ServerSocket::StartAccept(intptr_t fd) { 535 bool ServerSocket::StartAccept(intptr_t fd) {
519 ListenSocket* listen_socket = reinterpret_cast<ListenSocket*>(fd); 536 ListenSocket* listen_socket = reinterpret_cast<ListenSocket*>(fd);
520 listen_socket->EnsureInitialized(EventHandler::delegate()); 537 listen_socket->EnsureInitialized(EventHandler::delegate());
521 // Always keep 5 outstanding accepts going, to enhance performance. 538 // Always keep 5 outstanding accepts going, to enhance performance.
522 for (int i = 0; i < 5; i++) { 539 for (int i = 0; i < 5; i++) {
523 if (!listen_socket->IssueAccept()) { 540 if (!listen_socket->IssueAccept()) {
524 DWORD rc = WSAGetLastError(); 541 DWORD rc = WSAGetLastError();
525 listen_socket->Close(); 542 listen_socket->Close();
526 if (!listen_socket->HasPendingAccept()) { 543 if (!listen_socket->HasPendingAccept()) {
527 // Delete socket now, if there are no pending accepts. Otherwise, 544 // Delete socket now, if there are no pending accepts. Otherwise,
528 // the event-handler will take care of deleting it. 545 // the event-handler will take care of deleting it.
529 delete listen_socket; 546 listen_socket->Release();
530 } 547 }
531 SetLastError(rc); 548 SetLastError(rc);
532 return false; 549 return false;
533 } 550 }
534 } 551 }
535 return true; 552 return true;
536 } 553 }
537 554
538 555
539 void Socket::Close(intptr_t fd) { 556 void Socket::Close(intptr_t fd) {
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
664 return setsockopt(handle->socket(), proto, MCAST_LEAVE_GROUP, 681 return setsockopt(handle->socket(), proto, MCAST_LEAVE_GROUP,
665 reinterpret_cast<char*>(&mreq), sizeof(mreq)) == 0; 682 reinterpret_cast<char*>(&mreq), sizeof(mreq)) == 0;
666 } 683 }
667 684
668 } // namespace bin 685 } // namespace bin
669 } // namespace dart 686 } // namespace dart
670 687
671 #endif // defined(HOST_OS_WINDOWS) 688 #endif // defined(HOST_OS_WINDOWS)
672 689
673 #endif // !defined(DART_IO_DISABLED) 690 #endif // !defined(DART_IO_DISABLED)
OLDNEW
« no previous file with comments | « runtime/bin/socket_macos.cc ('k') | tests/standalone/io/socket_bind_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698