Flutter Engine
The Flutter Engine
Classes | Public Member Functions | Static Public Member Functions | List of all members
dart::bin::ListeningSocketRegistry Class Reference

#include <socket.h>

Public Member Functions

 ListeningSocketRegistry ()
 
 ~ListeningSocketRegistry ()
 
Dart_Handle CreateBindListen (Dart_Handle socket_object, RawAddr addr, intptr_t backlog, bool v6_only, bool shared)
 
Dart_Handle CreateUnixDomainBindListen (Dart_Handle socket_object, Namespace *namespc, const char *path, intptr_t backlog, bool shared)
 
bool CloseSafe (Socket *socketfd)
 
Mutexmutex ()
 

Static Public Member Functions

static void Initialize ()
 
static ListeningSocketRegistryInstance ()
 
static void Cleanup ()
 

Detailed Description

Definition at line 165 of file socket.h.

Constructor & Destructor Documentation

◆ ListeningSocketRegistry()

dart::bin::ListeningSocketRegistry::ListeningSocketRegistry ( )
inline

Definition at line 167 of file socket.h.

168 : sockets_by_port_(SameIntptrValue, kInitialSocketsCount),
169 sockets_by_fd_(SameIntptrValue, kInitialSocketsCount),
170 unix_domain_sockets_(nullptr),
171 mutex_() {}

◆ ~ListeningSocketRegistry()

dart::bin::ListeningSocketRegistry::~ListeningSocketRegistry ( )
inline

Definition at line 173 of file socket.h.

173{ CloseAllSafe(); }

Member Function Documentation

◆ Cleanup()

void dart::bin::ListeningSocketRegistry::Cleanup ( )
static

Definition at line 42 of file socket.cc.

42 {
45}
ListeningSocketRegistry * globalTcpListeningSocketRegistry
Definition: socket.cc:28

◆ CloseSafe()

bool dart::bin::ListeningSocketRegistry::CloseSafe ( Socket socketfd)

Definition at line 350 of file socket.cc.

350 {
351 ASSERT(!mutex_.TryLock());
352 OSSocket* os_socket = LookupByFd(socketfd);
353 if (os_socket != nullptr) {
354 return CloseOneSafe(os_socket, socketfd);
355 } else {
356 // A finalizer may direct the event handler to close a listening socket
357 // that it has never seen before. In this case, we return true to direct
358 // the eventhandler to clean up the socket.
359 return true;
360 }
361}
#define ASSERT(E)

◆ CreateBindListen()

Dart_Handle dart::bin::ListeningSocketRegistry::CreateBindListen ( Dart_Handle  socket_object,
RawAddr  addr,
intptr_t  backlog,
bool  v6_only,
bool  shared 
)

Definition at line 94 of file socket.cc.

98 {
99 MutexLocker ml(&mutex_);
100
101 OSSocket* first_os_socket = nullptr;
103 if (port > 0) {
104 first_os_socket = LookupByPort(port);
105 if (first_os_socket != nullptr) {
106 // There is already a socket listening on this port. We need to ensure
107 // that if there is one also listening on the same address, it was created
108 // with `shared = true`, ...
109 OSSocket* os_socket = first_os_socket;
110 OSSocket* os_socket_same_addr = FindOSSocketWithAddress(os_socket, addr);
111
112 if (os_socket_same_addr != nullptr) {
113 if (!os_socket_same_addr->shared || !shared) {
114 OSError os_error(-1,
115 "The shared flag to bind() needs to be `true` if "
116 "binding multiple times on the same (address, port) "
117 "combination.",
119 return DartUtils::NewDartOSError(&os_error);
120 }
121 if (os_socket_same_addr->v6_only != v6_only) {
122 OSError os_error(-1,
123 "The v6Only flag to bind() needs to be the same if "
124 "binding multiple times on the same (address, port) "
125 "combination.",
127 return DartUtils::NewDartOSError(&os_error);
128 }
129
130 // This socket creation is the exact same as the one which originally
131 // created the socket. Feed same fd and store it into native field
132 // of dart socket_object. Sockets here will share same fd but contain a
133 // different port() through EventHandler_SendData.
134 Socket* socketfd = new Socket(os_socket_same_addr->fd);
135 os_socket_same_addr->ref_count++;
136 // We set as a side-effect the file descriptor on the dart
137 // socket_object.
138 Socket::ReuseSocketIdNativeField(socket_object, socketfd,
140 InsertByFd(socketfd, os_socket_same_addr);
141 return Dart_True();
142 }
143 }
144 }
145
146 // There is no socket listening on that (address, port), so we create new one.
147 intptr_t fd = ServerSocket::CreateBindListen(addr, backlog, v6_only);
148 if (fd == -5) {
149 OSError os_error(-1, "Invalid host", OSError::kUnknown);
150 return DartUtils::NewDartOSError(&os_error);
151 }
152 if (fd < 0) {
153 OSError error;
155 }
156 if (!ServerSocket::StartAccept(fd)) {
157 OSError os_error(-1, "Failed to start accept", OSError::kUnknown);
158 return DartUtils::NewDartOSError(&os_error);
159 }
160 intptr_t allocated_port = SocketBase::GetPort(fd);
161 ASSERT(allocated_port > 0);
162
163 if (allocated_port != port) {
164 // There are two cases to consider:
165 //
166 // a) The user requested (address, port) where port != 0 which means
167 // we re-use an existing socket if available (and it is shared) or we
168 // create a new one. The new socket is guaranteed to have that
169 // selected port.
170 //
171 // b) The user requested (address, 0). This will make us *always* create a
172 // new socket. The OS will assign it a new `allocated_port` and we will
173 // insert into our data structures. *BUT* There might already be an
174 // existing (address2, `allocated_port`) where address != address2. So
175 // we need to do another `LookupByPort(allocated_port)` and link them
176 // via `OSSocket->next`.
177 ASSERT(port == 0);
178 first_os_socket = LookupByPort(allocated_port);
179 }
180
181 Socket* socketfd = new Socket(fd);
182 OSSocket* os_socket =
183 new OSSocket(addr, allocated_port, v6_only, shared, socketfd, nullptr);
184 os_socket->ref_count = 1;
185 os_socket->next = first_os_socket;
186
187 InsertByPort(allocated_port, os_socket);
188 InsertByFd(socketfd, os_socket);
189
190 // We set as a side-effect the port on the dart socket_object.
191 Socket::ReuseSocketIdNativeField(socket_object, socketfd,
193
194 return Dart_True();
195}
static Dart_Handle NewDartOSError()
Definition: dartutils.cc:702
static intptr_t CreateBindListen(const RawAddr &addr, intptr_t backlog, bool v6_only=false)
static bool StartAccept(intptr_t fd)
static intptr_t GetAddrPort(const RawAddr &addr)
Definition: socket_base.cc:187
static intptr_t GetPort(intptr_t fd)
static void ReuseSocketIdNativeField(Dart_Handle handle, Socket *socket, SocketFinalizer finalizer)
Definition: socket.cc:1456
@ kFinalizerListening
Definition: socket.h:37
const uint8_t uint32_t uint32_t GError ** error
DART_EXPORT Dart_Handle Dart_True()
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service port
Definition: switches.h:87

◆ CreateUnixDomainBindListen()

Dart_Handle dart::bin::ListeningSocketRegistry::CreateUnixDomainBindListen ( Dart_Handle  socket_object,
Namespace namespc,
const char *  path,
intptr_t  backlog,
bool  shared 
)

Definition at line 197 of file socket.cc.

202 {
203 MutexLocker ml(&mutex_);
204
205 RawAddr addr;
208 if (!Dart_IsNull(result)) {
209 return result;
210 }
211
212#if defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_ANDROID)
213 // Abstract unix domain socket doesn't exist in file system.
214 if (File::Exists(namespc, addr.un.sun_path) && path[0] != '@') {
215#else
216 if (File::Exists(namespc, addr.un.sun_path)) {
217#endif // defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_ANDROID)
218 if (unix_domain_sockets_ != nullptr) {
219 // If there is a socket listening on this file. Ensure
220 // that it was created with `shared` mode and current `shared`
221 // is also true.
222 OSSocket* os_socket = unix_domain_sockets_;
223 OSSocket* os_socket_same_addr =
224 FindOSSocketWithPath(os_socket, namespc, addr.un.sun_path);
225 if (os_socket_same_addr != nullptr) {
226 if (!os_socket_same_addr->shared || !shared) {
227 OSError os_error(-1,
228 "The shared flag to bind() needs to be `true` if "
229 "binding multiple times on the same path.",
231 return DartUtils::NewDartOSError(&os_error);
232 }
233
234 // This socket creation is the exact same as the one which originally
235 // created the socket. Feed the same fd and store it into the native
236 // field of dart socket_object. Sockets here will share same fd but
237 // contain a different port() through EventHandler_SendData.
238 Socket* socketfd = new Socket(os_socket_same_addr->fd);
239 os_socket_same_addr->ref_count++;
240 // We set as a side-effect the file descriptor on the dart
241 // socket_object.
242 Socket::ReuseSocketIdNativeField(socket_object, socketfd,
244 InsertByFd(socketfd, os_socket_same_addr);
245 return Dart_True();
246 }
247 }
248 // Unix domain socket by default doesn't allow binding to an existing file.
249 // An error (EADDRINUSE) will be returned back. However, hanging is noticed
250 // on Android so we throw an exception for all platforms.
251 OSError os_error(-1, "File exists with given unix domain address",
253 return DartUtils::NewDartOSError(&os_error);
254 }
255
256 // There is no socket listening on that path, so we create new one.
257 intptr_t fd = ServerSocket::CreateUnixDomainBindListen(addr, backlog);
258
259 if (fd < 0) {
261 }
262
263 Socket* socketfd = new Socket(fd);
264 OSSocket* os_socket =
265 new OSSocket(addr, -1, false, shared, socketfd, namespc);
266 os_socket->ref_count = 1;
267 os_socket->next = unix_domain_sockets_;
268 unix_domain_sockets_ = os_socket;
269 InsertByFd(socketfd, os_socket);
270
271 Socket::ReuseSocketIdNativeField(socket_object, socketfd,
273
274 return Dart_True();
275}
static bool Exists(Namespace *namespc, const char *path)
static intptr_t CreateUnixDomainBindListen(const RawAddr &addr, intptr_t backlog)
static Dart_Handle GetUnixDomainSockAddr(const char *path, Namespace *namespc, RawAddr *addr)
Definition: socket_base.cc:130
struct _Dart_Handle * Dart_Handle
Definition: dart_api.h:258
GAsyncResult * result
DART_EXPORT bool Dart_IsNull(Dart_Handle object)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57

◆ Initialize()

void dart::bin::ListeningSocketRegistry::Initialize ( )
static

◆ Instance()

ListeningSocketRegistry * dart::bin::ListeningSocketRegistry::Instance ( )
static

Definition at line 38 of file socket.cc.

38 {
40}

◆ mutex()

Mutex * dart::bin::ListeningSocketRegistry::mutex ( )
inline

Definition at line 210 of file socket.h.

210{ return &mutex_; }

The documentation for this class was generated from the following files: