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

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

Issue 2533303005: VM: Fix memory leak during shutdown (Closed)
Patch Set: Created 4 years 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
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 "bin/socket.h" 7 #include "bin/socket.h"
8 8
9 #include "bin/dartutils.h" 9 #include "bin/dartutils.h"
10 #include "bin/io_buffer.h" 10 #include "bin/io_buffer.h"
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 83
84 84
85 void ListeningSocketRegistry::InsertByFd(intptr_t fd, OSSocket* socket) { 85 void ListeningSocketRegistry::InsertByFd(intptr_t fd, OSSocket* socket) {
86 HashMap::Entry* entry = sockets_by_fd_.Lookup( 86 HashMap::Entry* entry = sockets_by_fd_.Lookup(
87 GetHashmapKeyFromIntptr(fd), GetHashmapHashFromIntptr(fd), true); 87 GetHashmapKeyFromIntptr(fd), GetHashmapHashFromIntptr(fd), true);
88 ASSERT(entry != NULL); 88 ASSERT(entry != NULL);
89 entry->value = reinterpret_cast<void*>(socket); 89 entry->value = reinterpret_cast<void*>(socket);
90 } 90 }
91 91
92 92
93 void ListeningSocketRegistry::RemoveByFd(intptr_t fd) { 93 void ListeningSocketRegistry::RemoveByFd(intptr_t fd,
94 sockets_by_fd_.Remove(GetHashmapKeyFromIntptr(fd), 94 HashMap::Entry** map_cursor) {
95 GetHashmapHashFromIntptr(fd)); 95 void* key = GetHashmapKeyFromIntptr(fd);
96 uint32_t hash_code = GetHashmapHashFromIntptr(fd);
97 if (map_cursor != NULL) {
98 HashMap::Entry* entry = sockets_by_fd_.Lookup(key, hash_code, false);
99 ASSERT(entry != NULL);
100 *map_cursor = sockets_by_fd_.Remove(entry);
101 } else {
102 sockets_by_fd_.Remove(key, hash_code);
103 }
96 } 104 }
97 105
98 106
99 Dart_Handle ListeningSocketRegistry::CreateBindListen(Dart_Handle socket_object, 107 Dart_Handle ListeningSocketRegistry::CreateBindListen(Dart_Handle socket_object,
100 RawAddr addr, 108 RawAddr addr,
101 intptr_t backlog, 109 intptr_t backlog,
102 bool v6_only, 110 bool v6_only,
103 bool shared) { 111 bool shared) {
104 MutexLocker ml(mutex_); 112 MutexLocker ml(mutex_);
105 113
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 InsertByPort(allocated_port, os_socket); 197 InsertByPort(allocated_port, os_socket);
190 InsertByFd(socketfd, os_socket); 198 InsertByFd(socketfd, os_socket);
191 199
192 // We set as a side-effect the port on the dart socket_object. 200 // We set as a side-effect the port on the dart socket_object.
193 Socket::SetSocketIdNativeField(socket_object, socketfd); 201 Socket::SetSocketIdNativeField(socket_object, socketfd);
194 202
195 return Dart_True(); 203 return Dart_True();
196 } 204 }
197 205
198 206
199 bool ListeningSocketRegistry::CloseOneSafe(OSSocket* os_socket) { 207 bool ListeningSocketRegistry::CloseOneSafe(OSSocket* os_socket,
Vyacheslav Egorov (Google) 2016/11/30 12:41:56 I suggest a much simple approach: pass a boolean h
208 HashMap::Entry** fd_map_cursor) {
200 ASSERT(!mutex_->TryLock()); 209 ASSERT(!mutex_->TryLock());
201 ASSERT(os_socket != NULL); 210 ASSERT(os_socket != NULL);
202 ASSERT(os_socket->ref_count > 0); 211 ASSERT(os_socket->ref_count > 0);
203 os_socket->ref_count--; 212 os_socket->ref_count--;
204 if (os_socket->ref_count > 0) { 213 if (os_socket->ref_count > 0) {
205 return false; 214 return false;
206 } 215 }
207 // We free the OS socket by removing it from two datastructures. 216 // We free the OS socket by removing it from two datastructures.
208 RemoveByFd(os_socket->socketfd); 217 RemoveByFd(os_socket->socketfd, fd_map_cursor);
209 218
210 OSSocket* prev = NULL; 219 OSSocket* prev = NULL;
211 OSSocket* current = LookupByPort(os_socket->port); 220 OSSocket* current = LookupByPort(os_socket->port);
212 while (current != os_socket) { 221 while (current != os_socket) {
213 ASSERT(current != NULL); 222 ASSERT(current != NULL);
214 prev = current; 223 prev = current;
215 current = current->next; 224 current = current->next;
216 } 225 }
217 226
218 if ((prev == NULL) && (current->next == NULL)) { 227 if ((prev == NULL) && (current->next == NULL)) {
219 // Remove last element from the list. 228 // Remove last element from the list.
220 RemoveByPort(os_socket->port); 229 RemoveByPort(os_socket->port);
221 } else if (prev == NULL) { 230 } else if (prev == NULL) {
222 // Remove first element of the list. 231 // Remove first element of the list.
223 InsertByPort(os_socket->port, current->next); 232 InsertByPort(os_socket->port, current->next);
224 } else { 233 } else {
225 // Remove element from the list which is not the first one. 234 // Remove element from the list which is not the first one.
226 prev->next = os_socket->next; 235 prev->next = os_socket->next;
227 } 236 }
228 237
229 ASSERT(os_socket->ref_count == 0); 238 ASSERT(os_socket->ref_count == 0);
230 delete os_socket; 239 delete os_socket;
231 return true; 240 return true;
232 } 241 }
233 242
234 243
235 void ListeningSocketRegistry::CloseAllSafe() { 244 void ListeningSocketRegistry::CloseAllSafe() {
236 MutexLocker ml(mutex_); 245 MutexLocker ml(mutex_);
237 for (HashMap::Entry* p = sockets_by_fd_.Start(); p != NULL; 246
238 p = sockets_by_fd_.Next(p)) { 247 HashMap::Entry* fd_map_cursor = sockets_by_fd_.Start();
239 CloseOneSafe(reinterpret_cast<OSSocket*>(p->value)); 248 while (fd_map_cursor != NULL) {
249 OSSocket* os_socket = reinterpret_cast<OSSocket*>(fd_map_cursor->value);
250 bool removed = CloseOneSafe(os_socket, &fd_map_cursor);
251 if (!removed) {
252 fd_map_cursor = sockets_by_fd_.Next(fd_map_cursor);
253 }
240 } 254 }
241 } 255 }
242 256
243 257
244 bool ListeningSocketRegistry::CloseSafe(intptr_t socketfd) { 258 bool ListeningSocketRegistry::CloseSafe(intptr_t socketfd) {
245 ASSERT(!mutex_->TryLock()); 259 ASSERT(!mutex_->TryLock());
246 OSSocket* os_socket = LookupByFd(socketfd); 260 OSSocket* os_socket = LookupByFd(socketfd);
247 if (os_socket != NULL) { 261 if (os_socket != NULL) {
248 return CloseOneSafe(os_socket); 262 return CloseOneSafe(os_socket, NULL);
249 } else { 263 } else {
250 // It should be impossible for the event handler to close something that 264 // It should be impossible for the event handler to close something that
251 // hasn't been created before. 265 // hasn't been created before.
252 UNREACHABLE(); 266 UNREACHABLE();
253 return false; 267 return false;
254 } 268 }
255 } 269 }
256 270
257 271
258 void FUNCTION_NAME(InternetAddress_Parse)(Dart_NativeArguments args) { 272 void FUNCTION_NAME(InternetAddress_Parse)(Dart_NativeArguments args) {
(...skipping 682 matching lines...) Expand 10 before | Expand all | Expand 10 after
941 if (Dart_IsError(err)) { 955 if (Dart_IsError(err)) {
942 Dart_PropagateError(err); 956 Dart_PropagateError(err);
943 } 957 }
944 return socket; 958 return socket;
945 } 959 }
946 960
947 } // namespace bin 961 } // namespace bin
948 } // namespace dart 962 } // namespace dart
949 963
950 #endif // !defined(DART_IO_DISABLED) 964 #endif // !defined(DART_IO_DISABLED)
OLDNEW
« no previous file with comments | « runtime/bin/socket.h ('k') | runtime/platform/hashmap.h » ('j') | runtime/platform/hashmap.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698