Chromium Code Reviews| Index: dart/runtime/bin/socket.h |
| diff --git a/dart/runtime/bin/socket.h b/dart/runtime/bin/socket.h |
| index 831e1dddb6e8d1fb42b2d693d035728425710541..b830c6aeda06271d4cdbc96ad26ff6b9c7766d57 100644 |
| --- a/dart/runtime/bin/socket.h |
| +++ b/dart/runtime/bin/socket.h |
| @@ -5,6 +5,8 @@ |
| #ifndef BIN_SOCKET_H_ |
| #define BIN_SOCKET_H_ |
| +#include <map> |
| + |
| #include "platform/globals.h" |
| #include "bin/builtin.h" |
| @@ -76,6 +78,21 @@ class SocketAddress { |
| sizeof(struct in6_addr) : sizeof(struct in_addr); |
| } |
| + static bool AreAddressesEqual(const RawAddr& a, const RawAddr& b) { |
| + if (a.ss.ss_family == AF_INET) { |
| + if (b.ss.ss_family != AF_INET) return false; |
| + return memcmp(&a.in.sin_addr, &b.in.sin_addr, sizeof(a.in.sin_addr)) == 0; |
| + } else if (a.ss.ss_family == AF_INET6) { |
| + if (b.ss.ss_family != AF_INET6) return false; |
| + return memcmp(&a.in6.sin6_addr, |
| + &b.in6.sin6_addr, |
| + sizeof(a.in6.sin6_addr)) == 0; |
| + } else { |
| + UNREACHABLE(); |
| + return false; |
| + } |
| + } |
| + |
| static void GetSockAddr(Dart_Handle obj, RawAddr* addr) { |
| Dart_TypedData_Type data_type; |
| uint8_t* data = NULL; |
| @@ -311,6 +328,88 @@ class ServerSocket { |
| DISALLOW_IMPLICIT_CONSTRUCTORS(ServerSocket); |
| }; |
| +class ListeningSocketRegistry { |
| + private: |
| + struct OSSocket { |
| + RawAddr address; |
| + int port; |
| + bool v6_only; |
| + bool shared; |
| + int ref_count; |
| + intptr_t socketfd; |
| + |
| + // Singly linked lists of OSSocket instances which listen on the same port |
| + // but on different addresses. |
| + OSSocket *next; |
| + |
| + OSSocket(RawAddr address, int port, bool v6_only, bool shared, |
| + intptr_t socketfd) |
| + : address(address), port(port), v6_only(v6_only), shared(shared), |
| + ref_count(0), socketfd(socketfd), next(NULL) {} |
| + }; |
| + |
| + public: |
| + static bool Initialize(); |
| + |
| + static ListeningSocketRegistry *Instance(); |
| + |
| + static void Cleanup(); |
| + |
| + |
| + ListeningSocketRegistry() : mutex_(new Mutex()) {} |
| + |
| + ~ListeningSocketRegistry() { |
| + delete mutex_; |
| + mutex_ = NULL; |
| + } |
| + |
| + // This function should be called from a dart runtime call in order to create |
| + // a new (potentially shared) socket. |
| + Dart_Handle CreateBindListen(Dart_Handle socket_object, |
| + RawAddr addr, |
| + intptr_t port, |
| + intptr_t backlog, |
| + bool v6_only, |
| + bool shared); |
| + |
| + // This should be called from the event handler for every kCloseEvent it gets |
| + // on listening sockets. |
| + // |
| + // Returns `true` if the last reference has been dropped and the underlying |
| + // socket can be closed. |
| + // |
| + // The caller is responsible for obtaining the mutex first, before calling |
| + // this function. |
| + bool CloseSafe(intptr_t socketfd); |
| + |
| + // Mark an existing socket as sharable if it is not already marked as |
| + // sharable. |
| + // |
| + // NOTE: This is a temporary measure until ServerSocketReference's are |
| + // removed. |
| + Dart_Handle MarkSocketFdAsSharableHack(intptr_t socketfd); |
| + |
| + Mutex *mutex() { return mutex_; } |
| + |
| + private: |
| + OSSocket *findOSSocketWithAddress(OSSocket *current, const RawAddr& addr) { |
| + while (current != NULL) { |
| + if (SocketAddress::AreAddressesEqual(current->address, addr)) { |
| + return current; |
| + } |
| + current = current->next; |
| + } |
| + return NULL; |
| + } |
| + |
| + std::map<intptr_t, OSSocket*> sockets_by_port_; |
| + std::map<intptr_t, OSSocket*> sockets_by_fd_; |
| + Mutex *mutex_; |
| + |
| + typedef std::map<intptr_t, OSSocket*>::iterator SocketsIterator; |
|
Søren Gjesse
2015/02/11 08:51:05
Please add
DISALLOW_COPY_AND_ASSIGN(ListeningSock
kustermann
2015/02/11 09:56:09
Done.
|
| +}; |
| + |
| + |
| } // namespace bin |
| } // namespace dart |