Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(348)

Side by Side Diff: runtime/bin/socket_common.h

Issue 2780063002: Pulled a significant portion of Socket implementation into BaseSocket in order to prepare for the s… (Closed)
Patch Set: Updated copyright date, fixed incorrect items in socket_common_macos.h Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2017, 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 RUNTIME_BIN_SOCKET_H_ 5 #ifndef RUNTIME_BIN_SOCKET_COMMON_H_
6 #define RUNTIME_BIN_SOCKET_H_ 6 #define RUNTIME_BIN_SOCKET_COMMON_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_common.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_common_android.h"
16 #elif defined(TARGET_OS_FUCHSIA) 16 #elif defined(TARGET_OS_FUCHSIA)
17 #include "bin/socket_fuchsia.h" 17 #include "bin/socket_common_fuchsia.h"
18 #elif defined(TARGET_OS_LINUX) 18 #elif defined(TARGET_OS_LINUX)
19 #include "bin/socket_linux.h" 19 #include "bin/socket_common_linux.h"
20 #elif defined(TARGET_OS_MACOS) 20 #elif defined(TARGET_OS_MACOS)
21 #include "bin/socket_macos.h" 21 #include "bin/socket_common_macos.h"
22 #elif defined(TARGET_OS_WINDOWS) 22 #elif defined(TARGET_OS_WINDOWS)
23 #include "bin/socket_win.h" 23 #include "bin/socket_common_win.h"
24 #else 24 #else
25 #error Unknown target os. 25 #error Unknown target os.
26 #endif 26 #endif
27 27
28 #include "bin/builtin.h" 28 #include "bin/builtin.h"
29 #include "bin/dartutils.h" 29 #include "bin/dartutils.h"
30 #include "bin/thread.h" 30 #include "bin/thread.h"
31 #include "bin/utils.h" 31 #include "bin/utils.h"
32 #include "platform/hashmap.h" 32 #include "platform/hashmap.h"
33 33
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 void SetAt(intptr_t i, T* addr) { addresses_[i] = addr; } 240 void SetAt(intptr_t i, T* addr) { addresses_[i] = addr; }
241 241
242 private: 242 private:
243 const intptr_t count_; 243 const intptr_t count_;
244 T** addresses_; 244 T** addresses_;
245 245
246 DISALLOW_COPY_AND_ASSIGN(AddressList); 246 DISALLOW_COPY_AND_ASSIGN(AddressList);
247 }; 247 };
248 248
249 249
250 class Socket { 250 class BaseSocket {
251 public: 251 public:
252 enum SocketRequest { 252 enum SocketRequest {
253 kLookupRequest = 0, 253 kLookupRequest = 0,
254 kListInterfacesRequest = 1, 254 kListInterfacesRequest = 1,
255 kReverseLookupRequest = 2, 255 kReverseLookupRequest = 2,
256 }; 256 };
257 257
258 static bool Initialize(); 258 static bool Initialize();
259 static intptr_t Available(intptr_t fd); 259 static intptr_t Available(intptr_t fd);
260 static intptr_t Read(intptr_t fd, void* buffer, intptr_t num_bytes); 260 static intptr_t Read(intptr_t fd, void* buffer, intptr_t num_bytes);
261 static intptr_t Write(intptr_t fd, const void* buffer, intptr_t num_bytes); 261 static intptr_t Write(intptr_t fd, const void* buffer, intptr_t num_bytes);
262 // Send data on a socket. The port to send to is specified in the port 262 // Send data on a socket. The port to send to is specified in the port
263 // component of the passed RawAddr structure. The RawAddr structure is only 263 // component of the passed RawAddr structure. The RawAddr structure is only
264 // used for datagram sockets. 264 // used for datagram sockets.
265 static intptr_t SendTo(intptr_t fd, 265 static intptr_t SendTo(intptr_t fd,
266 const void* buffer, 266 const void* buffer,
267 intptr_t num_bytes, 267 intptr_t num_bytes,
268 const RawAddr& addr); 268 const RawAddr& addr);
269 static intptr_t RecvFrom(intptr_t fd, 269 static intptr_t RecvFrom(intptr_t fd,
270 void* buffer, 270 void* buffer,
271 intptr_t num_bytes, 271 intptr_t num_bytes,
272 RawAddr* addr); 272 RawAddr* addr);
273 // Creates a socket which is bound and connected. The port to connect to is
274 // specified as the port component of the passed RawAddr structure.
275 static intptr_t CreateConnect(const RawAddr& addr);
276 // Creates a socket which is bound and connected. The port to connect to is
277 // specified as the port component of the passed RawAddr structure.
278 static intptr_t CreateBindConnect(const RawAddr& addr,
279 const RawAddr& source_addr);
280 // Returns true if the given error-number is because the system was not able 273 // Returns true if the given error-number is because the system was not able
281 // to bind the socket to a specific IP. 274 // to bind the socket to a specific IP.
282 static bool IsBindError(intptr_t error_number); 275 static bool IsBindError(intptr_t error_number);
283 // Creates a datagram socket which is bound. The port to bind
284 // to is specified as the port component of the RawAddr structure.
285 static intptr_t CreateBindDatagram(const RawAddr& addr, bool reuseAddress);
286 static intptr_t GetPort(intptr_t fd); 276 static intptr_t GetPort(intptr_t fd);
287 static SocketAddress* GetRemotePeer(intptr_t fd, intptr_t* port); 277 static SocketAddress* GetRemotePeer(intptr_t fd, intptr_t* port);
288 static void GetError(intptr_t fd, OSError* os_error); 278 static void GetError(intptr_t fd, OSError* os_error);
289 static int GetType(intptr_t fd); 279 static int GetType(intptr_t fd);
290 static intptr_t GetStdioHandle(intptr_t num); 280 static intptr_t GetStdioHandle(intptr_t num);
291 static void Close(intptr_t fd); 281 static void Close(intptr_t fd);
292 static bool GetNoDelay(intptr_t fd, bool* enabled); 282 static bool GetNoDelay(intptr_t fd, bool* enabled);
293 static bool SetNoDelay(intptr_t fd, bool enabled); 283 static bool SetNoDelay(intptr_t fd, bool enabled);
294 static bool GetMulticastLoop(intptr_t fd, intptr_t protocol, bool* enabled); 284 static bool GetMulticastLoop(intptr_t fd, intptr_t protocol, bool* enabled);
295 static bool SetMulticastLoop(intptr_t fd, intptr_t protocol, bool enabled); 285 static bool SetMulticastLoop(intptr_t fd, intptr_t protocol, bool enabled);
(...skipping 24 matching lines...) Expand all
320 static bool FormatNumericAddress(const RawAddr& addr, char* address, int len); 310 static bool FormatNumericAddress(const RawAddr& addr, char* address, int len);
321 311
322 // Whether ListInterfaces is supported. 312 // Whether ListInterfaces is supported.
323 static bool ListInterfacesSupported(); 313 static bool ListInterfacesSupported();
324 314
325 // List interfaces. Returns a AddressList of InterfaceSocketAddress's. 315 // List interfaces. Returns a AddressList of InterfaceSocketAddress's.
326 static AddressList<InterfaceSocketAddress>* ListInterfaces( 316 static AddressList<InterfaceSocketAddress>* ListInterfaces(
327 int type, 317 int type,
328 OSError** os_error); 318 OSError** os_error);
329 319
330 static CObject* LookupRequest(const CObjectArray& request);
331 static CObject* ListInterfacesRequest(const CObjectArray& request);
332 static CObject* ReverseLookupRequest(const CObjectArray& request);
333
334 static Dart_Port GetServicePort(); 320 static Dart_Port GetServicePort();
335 321
336 static void SetSocketIdNativeField(Dart_Handle socket, intptr_t id); 322 static void SetSocketIdNativeField(Dart_Handle socket, intptr_t id);
337 static intptr_t GetSocketIdNativeField(Dart_Handle socket); 323 static intptr_t GetSocketIdNativeField(Dart_Handle socket);
338 324
339 private: 325 private:
340 DISALLOW_ALLOCATION(); 326 DISALLOW_ALLOCATION();
341 DISALLOW_IMPLICIT_CONSTRUCTORS(Socket); 327 DISALLOW_IMPLICIT_CONSTRUCTORS(BaseSocket);
342 };
343
344
345 class ServerSocket {
346 public:
347 static const intptr_t kTemporaryFailure = -2;
348
349 static intptr_t Accept(intptr_t fd);
350
351 // Creates a socket which is bound and listens. The port to listen on is
352 // specified in the port component of the passed RawAddr structure.
353 //
354 // Returns a positive integer if the call is successful. In case of failure
355 // it returns:
356 //
357 // -1: system error (errno set)
358 // -5: invalid bindAddress
359 static intptr_t CreateBindListen(const RawAddr& addr,
360 intptr_t backlog,
361 bool v6_only = false);
362
363 // Start accepting on a newly created listening socket. If it was unable to
364 // start accepting incoming sockets, the fd is invalidated.
365 static bool StartAccept(intptr_t fd);
366
367 private:
368 DISALLOW_ALLOCATION();
369 DISALLOW_IMPLICIT_CONSTRUCTORS(ServerSocket);
370 };
371
372
373 class ListeningSocketRegistry {
374 public:
375 ListeningSocketRegistry()
376 : sockets_by_port_(SameIntptrValue, kInitialSocketsCount),
377 sockets_by_fd_(SameIntptrValue, kInitialSocketsCount),
378 mutex_(new Mutex()) {}
379
380 ~ListeningSocketRegistry() {
381 CloseAllSafe();
382 delete mutex_;
383 mutex_ = NULL;
384 }
385
386 static void Initialize();
387
388 static ListeningSocketRegistry* Instance();
389
390 static void Cleanup();
391
392 // This function should be called from a dart runtime call in order to create
393 // a new (potentially shared) socket.
394 Dart_Handle CreateBindListen(Dart_Handle socket_object,
395 RawAddr addr,
396 intptr_t backlog,
397 bool v6_only,
398 bool shared);
399
400 // This should be called from the event handler for every kCloseEvent it gets
401 // on listening sockets.
402 //
403 // Returns `true` if the last reference has been dropped and the underlying
404 // socket can be closed.
405 //
406 // The caller is responsible for obtaining the mutex first, before calling
407 // this function.
408 bool CloseSafe(intptr_t socketfd);
409
410 Mutex* mutex() { return mutex_; }
411
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,
426 int port,
427 bool v6_only,
428 bool shared,
429 intptr_t socketfd)
430 : address(address),
431 port(port),
432 v6_only(v6_only),
433 shared(shared),
434 ref_count(0),
435 socketfd(socketfd),
436 next(NULL) {}
437 };
438
439 static const intptr_t kInitialSocketsCount = 8;
440
441 OSSocket* findOSSocketWithAddress(OSSocket* current, const RawAddr& addr) {
442 while (current != NULL) {
443 if (SocketAddress::AreAddressesEqual(current->address, addr)) {
444 return current;
445 }
446 current = current->next;
447 }
448 return NULL;
449 }
450
451 static bool SameIntptrValue(void* key1, void* key2) {
452 return reinterpret_cast<intptr_t>(key1) == reinterpret_cast<intptr_t>(key2);
453 }
454
455 static uint32_t GetHashmapHashFromIntptr(intptr_t i) {
456 return static_cast<uint32_t>((i + 1) & 0xFFFFFFFF);
457 }
458
459
460 static void* GetHashmapKeyFromIntptr(intptr_t i) {
461 return reinterpret_cast<void*>(i + 1);
462 }
463
464 OSSocket* LookupByPort(intptr_t port);
465 void InsertByPort(intptr_t port, OSSocket* socket);
466 void RemoveByPort(intptr_t port);
467
468 OSSocket* LookupByFd(intptr_t fd);
469 void InsertByFd(intptr_t fd, OSSocket* socket);
470 void RemoveByFd(intptr_t fd);
471
472 bool CloseOneSafe(OSSocket* os_socket, bool update_hash_maps);
473 void CloseAllSafe();
474
475 HashMap sockets_by_port_;
476 HashMap sockets_by_fd_;
477
478 Mutex* mutex_;
479
480 DISALLOW_COPY_AND_ASSIGN(ListeningSocketRegistry);
481 }; 328 };
482 329
483 } // namespace bin 330 } // namespace bin
484 } // namespace dart 331 } // namespace dart
485 332
486 #endif // RUNTIME_BIN_SOCKET_H_ 333 #endif // RUNTIME_BIN_SOCKET_COMMON_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698