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 RUNTIME_BIN_SOCKET_H_ | 5 #ifndef RUNTIME_BIN_SOCKET_H_ |
6 #define RUNTIME_BIN_SOCKET_H_ | 6 #define RUNTIME_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(HOST_OS_ANDROID) | 14 #if defined(HOST_OS_ANDROID) |
15 #include "bin/socket_android.h" | 15 #include "bin/socket_android.h" |
16 #elif defined(HOST_OS_FUCHSIA) | 16 #elif defined(HOST_OS_FUCHSIA) |
17 #include "bin/socket_fuchsia.h" | 17 #include "bin/socket_fuchsia.h" |
18 #elif defined(HOST_OS_LINUX) | 18 #elif defined(HOST_OS_LINUX) |
19 #include "bin/socket_linux.h" | 19 #include "bin/socket_linux.h" |
20 #elif defined(HOST_OS_MACOS) | 20 #elif defined(HOST_OS_MACOS) |
21 #include "bin/socket_macos.h" | 21 #include "bin/socket_macos.h" |
22 #elif defined(HOST_OS_WINDOWS) | 22 #elif defined(HOST_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 "bin/builtin.h" | 28 #include "bin/builtin.h" |
29 #include "bin/dartutils.h" | 29 #include "bin/dartutils.h" |
| 30 #include "bin/reference_counting.h" |
30 #include "bin/thread.h" | 31 #include "bin/thread.h" |
31 #include "bin/utils.h" | 32 #include "bin/utils.h" |
32 #include "platform/hashmap.h" | 33 #include "platform/hashmap.h" |
33 | 34 |
34 namespace dart { | 35 namespace dart { |
35 namespace bin { | 36 namespace bin { |
36 | 37 |
37 union RawAddr { | 38 union RawAddr { |
38 struct sockaddr_in in; | 39 struct sockaddr_in in; |
39 struct sockaddr_in6 in6; | 40 struct sockaddr_in6 in6; |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
240 void SetAt(intptr_t i, T* addr) { addresses_[i] = addr; } | 241 void SetAt(intptr_t i, T* addr) { addresses_[i] = addr; } |
241 | 242 |
242 private: | 243 private: |
243 const intptr_t count_; | 244 const intptr_t count_; |
244 T** addresses_; | 245 T** addresses_; |
245 | 246 |
246 DISALLOW_COPY_AND_ASSIGN(AddressList); | 247 DISALLOW_COPY_AND_ASSIGN(AddressList); |
247 }; | 248 }; |
248 | 249 |
249 | 250 |
250 class Socket { | 251 // We write Sockets into the native field of the _NativeSocket object |
| 252 // on the Dart side. They are allocated in SetSocketIdNativeField(), and are |
| 253 // deallocated either from the finalizer attached to _NativeSockets there, or |
| 254 // from the eventhandler, whichever drops the last reference. |
| 255 class Socket : public ReferenceCounted<Socket> { |
251 public: | 256 public: |
252 enum SocketRequest { | 257 enum SocketRequest { |
253 kLookupRequest = 0, | 258 kLookupRequest = 0, |
254 kListInterfacesRequest = 1, | 259 kListInterfacesRequest = 1, |
255 kReverseLookupRequest = 2, | 260 kReverseLookupRequest = 2, |
256 }; | 261 }; |
257 | 262 |
| 263 explicit Socket(intptr_t fd); |
| 264 |
| 265 intptr_t fd() const { return fd_; } |
| 266 void SetClosedFd(); |
| 267 |
| 268 Dart_Port port() const { return port_; } |
| 269 void set_port(Dart_Port port) { port_ = port; } |
| 270 |
| 271 // TODO(dart:io): Convert these to instance methods where possible. |
258 static bool Initialize(); | 272 static bool Initialize(); |
259 static intptr_t Available(intptr_t fd); | 273 static intptr_t Available(intptr_t fd); |
260 static intptr_t Read(intptr_t fd, void* buffer, intptr_t num_bytes); | 274 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); | 275 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 | 276 // 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 | 277 // component of the passed RawAddr structure. The RawAddr structure is only |
264 // used for datagram sockets. | 278 // used for datagram sockets. |
265 static intptr_t SendTo(intptr_t fd, | 279 static intptr_t SendTo(intptr_t fd, |
266 const void* buffer, | 280 const void* buffer, |
267 intptr_t num_bytes, | 281 intptr_t num_bytes, |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
326 static AddressList<InterfaceSocketAddress>* ListInterfaces( | 340 static AddressList<InterfaceSocketAddress>* ListInterfaces( |
327 int type, | 341 int type, |
328 OSError** os_error); | 342 OSError** os_error); |
329 | 343 |
330 static CObject* LookupRequest(const CObjectArray& request); | 344 static CObject* LookupRequest(const CObjectArray& request); |
331 static CObject* ListInterfacesRequest(const CObjectArray& request); | 345 static CObject* ListInterfacesRequest(const CObjectArray& request); |
332 static CObject* ReverseLookupRequest(const CObjectArray& request); | 346 static CObject* ReverseLookupRequest(const CObjectArray& request); |
333 | 347 |
334 static Dart_Port GetServicePort(); | 348 static Dart_Port GetServicePort(); |
335 | 349 |
336 static void SetSocketIdNativeField(Dart_Handle socket, intptr_t id); | 350 static void SetSocketIdNativeField(Dart_Handle handle, |
337 static intptr_t GetSocketIdNativeField(Dart_Handle socket); | 351 intptr_t id, |
| 352 bool listening); |
| 353 static void ReuseSocketIdNativeField(Dart_Handle handle, |
| 354 Socket* socket, |
| 355 bool listening); |
| 356 static Socket* GetSocketIdNativeField(Dart_Handle socket); |
338 | 357 |
339 private: | 358 private: |
340 DISALLOW_ALLOCATION(); | 359 ~Socket() { ASSERT(fd_ == kClosedFd); } |
341 DISALLOW_IMPLICIT_CONSTRUCTORS(Socket); | 360 |
| 361 static const int kClosedFd = -1; |
| 362 |
| 363 intptr_t fd_; |
| 364 Dart_Port port_; |
| 365 |
| 366 friend class ReferenceCounted<Socket>; |
| 367 DISALLOW_COPY_AND_ASSIGN(Socket); |
342 }; | 368 }; |
343 | 369 |
344 | 370 |
345 class ServerSocket { | 371 class ServerSocket { |
346 public: | 372 public: |
347 static const intptr_t kTemporaryFailure = -2; | 373 static const intptr_t kTemporaryFailure = -2; |
348 | 374 |
349 static intptr_t Accept(intptr_t fd); | 375 static intptr_t Accept(intptr_t fd); |
350 | 376 |
351 // Creates a socket which is bound and listens. The port to listen on is | 377 // Creates a socket which is bound and listens. The port to listen on is |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
398 bool shared); | 424 bool shared); |
399 | 425 |
400 // This should be called from the event handler for every kCloseEvent it gets | 426 // This should be called from the event handler for every kCloseEvent it gets |
401 // on listening sockets. | 427 // on listening sockets. |
402 // | 428 // |
403 // Returns `true` if the last reference has been dropped and the underlying | 429 // Returns `true` if the last reference has been dropped and the underlying |
404 // socket can be closed. | 430 // socket can be closed. |
405 // | 431 // |
406 // The caller is responsible for obtaining the mutex first, before calling | 432 // The caller is responsible for obtaining the mutex first, before calling |
407 // this function. | 433 // this function. |
408 bool CloseSafe(intptr_t socketfd); | 434 bool CloseSafe(Socket* socketfd); |
409 | 435 |
410 Mutex* mutex() { return mutex_; } | 436 Mutex* mutex() { return mutex_; } |
411 | 437 |
412 private: | 438 private: |
413 struct OSSocket { | 439 struct OSSocket { |
414 RawAddr address; | 440 RawAddr address; |
415 int port; | 441 int port; |
416 bool v6_only; | 442 bool v6_only; |
417 bool shared; | 443 bool shared; |
418 int ref_count; | 444 int ref_count; |
419 intptr_t socketfd; | 445 Socket* socketfd; |
420 | 446 |
421 // Singly linked lists of OSSocket instances which listen on the same port | 447 // Singly linked lists of OSSocket instances which listen on the same port |
422 // but on different addresses. | 448 // but on different addresses. |
423 OSSocket* next; | 449 OSSocket* next; |
424 | 450 |
425 OSSocket(RawAddr address, | 451 OSSocket(RawAddr address, |
426 int port, | 452 int port, |
427 bool v6_only, | 453 bool v6_only, |
428 bool shared, | 454 bool shared, |
429 intptr_t socketfd) | 455 Socket* socketfd) |
430 : address(address), | 456 : address(address), |
431 port(port), | 457 port(port), |
432 v6_only(v6_only), | 458 v6_only(v6_only), |
433 shared(shared), | 459 shared(shared), |
434 ref_count(0), | 460 ref_count(0), |
435 socketfd(socketfd), | 461 socketfd(socketfd), |
436 next(NULL) {} | 462 next(NULL) {} |
437 }; | 463 }; |
438 | 464 |
439 static const intptr_t kInitialSocketsCount = 8; | 465 static const intptr_t kInitialSocketsCount = 8; |
440 | 466 |
441 OSSocket* findOSSocketWithAddress(OSSocket* current, const RawAddr& addr) { | 467 OSSocket* FindOSSocketWithAddress(OSSocket* current, const RawAddr& addr) { |
442 while (current != NULL) { | 468 while (current != NULL) { |
443 if (SocketAddress::AreAddressesEqual(current->address, addr)) { | 469 if (SocketAddress::AreAddressesEqual(current->address, addr)) { |
444 return current; | 470 return current; |
445 } | 471 } |
446 current = current->next; | 472 current = current->next; |
447 } | 473 } |
448 return NULL; | 474 return NULL; |
449 } | 475 } |
450 | 476 |
451 static bool SameIntptrValue(void* key1, void* key2) { | 477 static bool SameIntptrValue(void* key1, void* key2) { |
452 return reinterpret_cast<intptr_t>(key1) == reinterpret_cast<intptr_t>(key2); | 478 return reinterpret_cast<intptr_t>(key1) == reinterpret_cast<intptr_t>(key2); |
453 } | 479 } |
454 | 480 |
455 static uint32_t GetHashmapHashFromIntptr(intptr_t i) { | 481 static uint32_t GetHashmapHashFromIntptr(intptr_t i) { |
456 return static_cast<uint32_t>((i + 1) & 0xFFFFFFFF); | 482 return static_cast<uint32_t>((i + 1) & 0xFFFFFFFF); |
457 } | 483 } |
458 | 484 |
459 | 485 |
460 static void* GetHashmapKeyFromIntptr(intptr_t i) { | 486 static void* GetHashmapKeyFromIntptr(intptr_t i) { |
461 return reinterpret_cast<void*>(i + 1); | 487 return reinterpret_cast<void*>(i + 1); |
462 } | 488 } |
463 | 489 |
464 OSSocket* LookupByPort(intptr_t port); | 490 OSSocket* LookupByPort(intptr_t port); |
465 void InsertByPort(intptr_t port, OSSocket* socket); | 491 void InsertByPort(intptr_t port, OSSocket* socket); |
466 void RemoveByPort(intptr_t port); | 492 void RemoveByPort(intptr_t port); |
467 | 493 |
468 OSSocket* LookupByFd(intptr_t fd); | 494 OSSocket* LookupByFd(Socket* fd); |
469 void InsertByFd(intptr_t fd, OSSocket* socket); | 495 void InsertByFd(Socket* fd, OSSocket* socket); |
470 void RemoveByFd(intptr_t fd); | 496 void RemoveByFd(Socket* fd); |
471 | 497 |
472 bool CloseOneSafe(OSSocket* os_socket, bool update_hash_maps); | 498 bool CloseOneSafe(OSSocket* os_socket, bool update_hash_maps); |
473 void CloseAllSafe(); | 499 void CloseAllSafe(); |
474 | 500 |
475 HashMap sockets_by_port_; | 501 HashMap sockets_by_port_; |
476 HashMap sockets_by_fd_; | 502 HashMap sockets_by_fd_; |
477 | 503 |
478 Mutex* mutex_; | 504 Mutex* mutex_; |
479 | 505 |
480 DISALLOW_COPY_AND_ASSIGN(ListeningSocketRegistry); | 506 DISALLOW_COPY_AND_ASSIGN(ListeningSocketRegistry); |
481 }; | 507 }; |
482 | 508 |
483 } // namespace bin | 509 } // namespace bin |
484 } // namespace dart | 510 } // namespace dart |
485 | 511 |
486 #endif // RUNTIME_BIN_SOCKET_H_ | 512 #endif // RUNTIME_BIN_SOCKET_H_ |
OLD | NEW |