Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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) |
| OLD | NEW |