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 |