| 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 #ifndef BIN_SOCKET_H_ | 5 #ifndef BIN_SOCKET_H_ |
| 6 #define BIN_SOCKET_H_ | 6 #define BIN_SOCKET_H_ |
| 7 | 7 |
| 8 #if defined(DART_IO_DISABLED) | 8 #if defined(DART_IO_DISABLED) |
| 9 #error "socket.h can only be included on builds with IO enabled" | 9 #error "socket.h can only be included on builds with IO enabled" |
| 10 #endif | 10 #endif |
| 11 | 11 |
| 12 #include "platform/globals.h" | 12 #include "platform/globals.h" |
| 13 // Declare the OS-specific types ahead of defining the generic class. | 13 // Declare the OS-specific types ahead of defining the generic class. |
| 14 #if defined(TARGET_OS_ANDROID) | 14 #if defined(TARGET_OS_ANDROID) |
| 15 #include "bin/socket_android.h" | 15 #include "bin/socket_android.h" |
| 16 #elif defined(TARGET_OS_FUCHSIA) | 16 #elif defined(TARGET_OS_FUCHSIA) |
| 17 #include "bin/socket_fuchsia.h" | 17 #include "bin/socket_fuchsia.h" |
| 18 #elif defined(TARGET_OS_LINUX) | 18 #elif defined(TARGET_OS_LINUX) |
| 19 #include "bin/socket_linux.h" | 19 #include "bin/socket_linux.h" |
| 20 #elif defined(TARGET_OS_MACOS) | 20 #elif defined(TARGET_OS_MACOS) |
| 21 #include "bin/socket_macos.h" | 21 #include "bin/socket_macos.h" |
| 22 #elif defined(TARGET_OS_WINDOWS) | 22 #elif defined(TARGET_OS_WINDOWS) |
| 23 #include "bin/socket_win.h" | 23 #include "bin/socket_win.h" |
| 24 #else | 24 #else |
| 25 #error Unknown target os. | 25 #error Unknown target os. |
| 26 #endif | 26 #endif |
| 27 | 27 |
| 28 #include <map> | |
| 29 | |
| 30 #include "bin/builtin.h" | 28 #include "bin/builtin.h" |
| 31 #include "bin/dartutils.h" | 29 #include "bin/dartutils.h" |
| 32 #include "bin/thread.h" | 30 #include "bin/thread.h" |
| 33 #include "bin/utils.h" | 31 #include "bin/utils.h" |
| 32 #include "platform/hashmap.h" |
| 34 | 33 |
| 35 namespace dart { | 34 namespace dart { |
| 36 namespace bin { | 35 namespace bin { |
| 37 | 36 |
| 38 union RawAddr { | 37 union RawAddr { |
| 39 struct sockaddr_in in; | 38 struct sockaddr_in in; |
| 40 struct sockaddr_in6 in6; | 39 struct sockaddr_in6 in6; |
| 41 struct sockaddr_storage ss; | 40 struct sockaddr_storage ss; |
| 42 struct sockaddr addr; | 41 struct sockaddr addr; |
| 43 }; | 42 }; |
| (...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 365 // start accepting incoming sockets, the fd is invalidated. | 364 // start accepting incoming sockets, the fd is invalidated. |
| 366 static bool StartAccept(intptr_t fd); | 365 static bool StartAccept(intptr_t fd); |
| 367 | 366 |
| 368 private: | 367 private: |
| 369 DISALLOW_ALLOCATION(); | 368 DISALLOW_ALLOCATION(); |
| 370 DISALLOW_IMPLICIT_CONSTRUCTORS(ServerSocket); | 369 DISALLOW_IMPLICIT_CONSTRUCTORS(ServerSocket); |
| 371 }; | 370 }; |
| 372 | 371 |
| 373 | 372 |
| 374 class ListeningSocketRegistry { | 373 class ListeningSocketRegistry { |
| 375 private: | 374 public: |
| 376 struct OSSocket { | 375 ListeningSocketRegistry() : |
| 377 RawAddr address; | 376 sockets_by_port_(SameIntptrValue, kInitialSocketsCount), |
| 378 int port; | 377 sockets_by_fd_(SameIntptrValue, kInitialSocketsCount), |
| 379 bool v6_only; | 378 mutex_(new Mutex()) {} |
| 380 bool shared; | |
| 381 int ref_count; | |
| 382 intptr_t socketfd; | |
| 383 | 379 |
| 384 // Singly linked lists of OSSocket instances which listen on the same port | 380 ~ListeningSocketRegistry() { |
| 385 // but on different addresses. | 381 CloseAllSafe(); |
| 386 OSSocket *next; | 382 delete mutex_; |
| 383 mutex_ = NULL; |
| 384 } |
| 387 | 385 |
| 388 OSSocket(RawAddr address, int port, bool v6_only, bool shared, | |
| 389 intptr_t socketfd) | |
| 390 : address(address), port(port), v6_only(v6_only), shared(shared), | |
| 391 ref_count(0), socketfd(socketfd), next(NULL) {} | |
| 392 }; | |
| 393 | |
| 394 public: | |
| 395 static void Initialize(); | 386 static void Initialize(); |
| 396 | 387 |
| 397 static ListeningSocketRegistry *Instance(); | 388 static ListeningSocketRegistry *Instance(); |
| 398 | 389 |
| 399 static void Cleanup(); | 390 static void Cleanup(); |
| 400 | 391 |
| 401 | |
| 402 ListeningSocketRegistry() : mutex_(new Mutex()) {} | |
| 403 | |
| 404 ~ListeningSocketRegistry() { | |
| 405 delete mutex_; | |
| 406 mutex_ = NULL; | |
| 407 } | |
| 408 | |
| 409 // This function should be called from a dart runtime call in order to create | 392 // This function should be called from a dart runtime call in order to create |
| 410 // a new (potentially shared) socket. | 393 // a new (potentially shared) socket. |
| 411 Dart_Handle CreateBindListen(Dart_Handle socket_object, | 394 Dart_Handle CreateBindListen(Dart_Handle socket_object, |
| 412 RawAddr addr, | 395 RawAddr addr, |
| 413 intptr_t backlog, | 396 intptr_t backlog, |
| 414 bool v6_only, | 397 bool v6_only, |
| 415 bool shared); | 398 bool shared); |
| 416 | 399 |
| 417 // This should be called from the event handler for every kCloseEvent it gets | 400 // This should be called from the event handler for every kCloseEvent it gets |
| 418 // on listening sockets. | 401 // on listening sockets. |
| 419 // | 402 // |
| 420 // Returns `true` if the last reference has been dropped and the underlying | 403 // Returns `true` if the last reference has been dropped and the underlying |
| 421 // socket can be closed. | 404 // socket can be closed. |
| 422 // | 405 // |
| 423 // The caller is responsible for obtaining the mutex first, before calling | 406 // The caller is responsible for obtaining the mutex first, before calling |
| 424 // this function. | 407 // this function. |
| 425 bool CloseSafe(intptr_t socketfd); | 408 bool CloseSafe(intptr_t socketfd); |
| 426 | 409 |
| 427 Mutex *mutex() { return mutex_; } | 410 Mutex *mutex() { return mutex_; } |
| 428 | 411 |
| 429 private: | 412 private: |
| 413 struct OSSocket { |
| 414 RawAddr address; |
| 415 int port; |
| 416 bool v6_only; |
| 417 bool shared; |
| 418 int ref_count; |
| 419 intptr_t socketfd; |
| 420 |
| 421 // Singly linked lists of OSSocket instances which listen on the same port |
| 422 // but on different addresses. |
| 423 OSSocket *next; |
| 424 |
| 425 OSSocket(RawAddr address, int port, bool v6_only, bool shared, |
| 426 intptr_t socketfd) |
| 427 : address(address), port(port), v6_only(v6_only), shared(shared), |
| 428 ref_count(0), socketfd(socketfd), next(NULL) {} |
| 429 }; |
| 430 |
| 431 static const intptr_t kInitialSocketsCount = 8; |
| 432 |
| 430 OSSocket *findOSSocketWithAddress(OSSocket *current, const RawAddr& addr) { | 433 OSSocket *findOSSocketWithAddress(OSSocket *current, const RawAddr& addr) { |
| 431 while (current != NULL) { | 434 while (current != NULL) { |
| 432 if (SocketAddress::AreAddressesEqual(current->address, addr)) { | 435 if (SocketAddress::AreAddressesEqual(current->address, addr)) { |
| 433 return current; | 436 return current; |
| 434 } | 437 } |
| 435 current = current->next; | 438 current = current->next; |
| 436 } | 439 } |
| 437 return NULL; | 440 return NULL; |
| 438 } | 441 } |
| 439 | 442 |
| 440 std::map<intptr_t, OSSocket*> sockets_by_port_; | 443 static bool SameIntptrValue(void* key1, void* key2) { |
| 441 std::map<intptr_t, OSSocket*> sockets_by_fd_; | 444 return reinterpret_cast<intptr_t>(key1) == reinterpret_cast<intptr_t>(key2); |
| 445 } |
| 446 |
| 447 static uint32_t GetHashmapHashFromIntptr(intptr_t i) { |
| 448 return static_cast<uint32_t>((i + 1) & 0xFFFFFFFF); |
| 449 } |
| 450 |
| 451 |
| 452 static void* GetHashmapKeyFromIntptr(intptr_t i) { |
| 453 return reinterpret_cast<void*>(i + 1); |
| 454 } |
| 455 |
| 456 OSSocket* LookupByPort(intptr_t port); |
| 457 void InsertByPort(intptr_t port, OSSocket* socket); |
| 458 void RemoveByPort(intptr_t port); |
| 459 |
| 460 OSSocket* LookupByFd(intptr_t fd); |
| 461 void InsertByFd(intptr_t fd, OSSocket* socket); |
| 462 void RemoveByFd(intptr_t fd); |
| 463 |
| 464 bool CloseOneSafe(OSSocket* os_socket); |
| 465 void CloseAllSafe(); |
| 466 |
| 467 HashMap sockets_by_port_; |
| 468 HashMap sockets_by_fd_; |
| 469 |
| 442 Mutex *mutex_; | 470 Mutex *mutex_; |
| 443 | 471 |
| 444 typedef std::map<intptr_t, OSSocket*>::iterator SocketsIterator; | |
| 445 | |
| 446 private: | |
| 447 DISALLOW_COPY_AND_ASSIGN(ListeningSocketRegistry); | 472 DISALLOW_COPY_AND_ASSIGN(ListeningSocketRegistry); |
| 448 }; | 473 }; |
| 449 | 474 |
| 450 } // namespace bin | 475 } // namespace bin |
| 451 } // namespace dart | 476 } // namespace dart |
| 452 | 477 |
| 453 #endif // BIN_SOCKET_H_ | 478 #endif // BIN_SOCKET_H_ |
| OLD | NEW |