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

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

Issue 2797993005: Re-land socket refactor with fixes for Windows. (Closed)
Patch Set: Rebased + reverted original revert 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
« no previous file with comments | « runtime/bin/socket_android.cc ('k') | runtime/bin/socket_base.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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_BASE_H_
6 #define RUNTIME_BIN_SOCKET_H_ 6 #define RUNTIME_BIN_SOCKET_BASE_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_base.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_base_android.h"
16 #elif defined(HOST_OS_FUCHSIA) 16 #elif defined(HOST_OS_FUCHSIA)
17 #include "bin/socket_fuchsia.h" 17 #include "bin/socket_base_fuchsia.h"
18 #elif defined(HOST_OS_LINUX) 18 #elif defined(HOST_OS_LINUX)
19 #include "bin/socket_linux.h" 19 #include "bin/socket_base_linux.h"
20 #elif defined(HOST_OS_MACOS) 20 #elif defined(HOST_OS_MACOS)
21 #include "bin/socket_macos.h" 21 #include "bin/socket_base_macos.h"
22 #elif defined(HOST_OS_WINDOWS) 22 #elif defined(HOST_OS_WINDOWS)
23 #include "bin/socket_win.h" 23 #include "bin/socket_base_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"
31 #include "bin/thread.h" 30 #include "bin/thread.h"
32 #include "bin/utils.h" 31 #include "bin/utils.h"
32 #include "platform/allocation.h"
33 #include "platform/hashmap.h" 33 #include "platform/hashmap.h"
34 34
35 namespace dart { 35 namespace dart {
36 namespace bin { 36 namespace bin {
37 37
38 union RawAddr { 38 union RawAddr {
39 struct sockaddr_in in; 39 struct sockaddr_in in;
40 struct sockaddr_in6 in6; 40 struct sockaddr_in6 in6;
41 struct sockaddr_storage ss; 41 struct sockaddr_storage ss;
42 struct sockaddr addr; 42 struct sockaddr addr;
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 T* GetAt(intptr_t i) const { return addresses_[i]; } 240 T* GetAt(intptr_t i) const { return addresses_[i]; }
241 void SetAt(intptr_t i, T* addr) { addresses_[i] = addr; } 241 void SetAt(intptr_t i, T* addr) { addresses_[i] = addr; }
242 242
243 private: 243 private:
244 const intptr_t count_; 244 const intptr_t count_;
245 T** addresses_; 245 T** addresses_;
246 246
247 DISALLOW_COPY_AND_ASSIGN(AddressList); 247 DISALLOW_COPY_AND_ASSIGN(AddressList);
248 }; 248 };
249 249
250 250 class SocketBase : public AllStatic {
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> {
256 public: 251 public:
257 enum SocketRequest { 252 enum SocketRequest {
258 kLookupRequest = 0, 253 kLookupRequest = 0,
259 kListInterfacesRequest = 1, 254 kListInterfacesRequest = 1,
260 kReverseLookupRequest = 2, 255 kReverseLookupRequest = 2,
261 }; 256 };
262 257
263 enum SocketFinalizer {
264 kFinalizerNormal,
265 kFinalizerListening,
266 kFinalizerStdio,
267 };
268
269 explicit Socket(intptr_t fd);
270
271 intptr_t fd() const { return fd_; }
272 void SetClosedFd();
273
274 Dart_Port port() const { return port_; }
275 void set_port(Dart_Port port) { port_ = port; }
276
277 // TODO(dart:io): Convert these to instance methods where possible. 258 // TODO(dart:io): Convert these to instance methods where possible.
278 static bool Initialize(); 259 static bool Initialize();
279 static intptr_t Available(intptr_t fd); 260 static intptr_t Available(intptr_t fd);
280 static intptr_t Read(intptr_t fd, void* buffer, intptr_t num_bytes); 261 static intptr_t Read(intptr_t fd, void* buffer, intptr_t num_bytes);
281 static intptr_t Write(intptr_t fd, const void* buffer, intptr_t num_bytes); 262 static intptr_t Write(intptr_t fd, const void* buffer, intptr_t num_bytes);
282 // Send data on a socket. The port to send to is specified in the port 263 // Send data on a socket. The port to send to is specified in the port
283 // component of the passed RawAddr structure. The RawAddr structure is only 264 // component of the passed RawAddr structure. The RawAddr structure is only
284 // used for datagram sockets. 265 // used for datagram sockets.
285 static intptr_t SendTo(intptr_t fd, 266 static intptr_t SendTo(intptr_t fd,
286 const void* buffer, 267 const void* buffer,
287 intptr_t num_bytes, 268 intptr_t num_bytes,
288 const RawAddr& addr); 269 const RawAddr& addr);
289 static intptr_t RecvFrom(intptr_t fd, 270 static intptr_t RecvFrom(intptr_t fd,
290 void* buffer, 271 void* buffer,
291 intptr_t num_bytes, 272 intptr_t num_bytes,
292 RawAddr* addr); 273 RawAddr* addr);
293 // Creates a socket which is bound and connected. The port to connect to is
294 // specified as the port component of the passed RawAddr structure.
295 static intptr_t CreateConnect(const RawAddr& addr);
296 // Creates a socket which is bound and connected. The port to connect to is
297 // specified as the port component of the passed RawAddr structure.
298 static intptr_t CreateBindConnect(const RawAddr& addr,
299 const RawAddr& source_addr);
300 // Returns true if the given error-number is because the system was not able 274 // Returns true if the given error-number is because the system was not able
301 // to bind the socket to a specific IP. 275 // to bind the socket to a specific IP.
302 static bool IsBindError(intptr_t error_number); 276 static bool IsBindError(intptr_t error_number);
303 // Creates a datagram socket which is bound. The port to bind
304 // to is specified as the port component of the RawAddr structure.
305 static intptr_t CreateBindDatagram(const RawAddr& addr, bool reuseAddress);
306 static intptr_t GetPort(intptr_t fd); 277 static intptr_t GetPort(intptr_t fd);
307 static SocketAddress* GetRemotePeer(intptr_t fd, intptr_t* port); 278 static SocketAddress* GetRemotePeer(intptr_t fd, intptr_t* port);
308 static void GetError(intptr_t fd, OSError* os_error); 279 static void GetError(intptr_t fd, OSError* os_error);
309 static int GetType(intptr_t fd); 280 static int GetType(intptr_t fd);
310 static intptr_t GetStdioHandle(intptr_t num); 281 static intptr_t GetStdioHandle(intptr_t num);
311 static void Close(intptr_t fd); 282 static void Close(intptr_t fd);
312 static bool GetNoDelay(intptr_t fd, bool* enabled); 283 static bool GetNoDelay(intptr_t fd, bool* enabled);
313 static bool SetNoDelay(intptr_t fd, bool enabled); 284 static bool SetNoDelay(intptr_t fd, bool enabled);
314 static bool GetMulticastLoop(intptr_t fd, intptr_t protocol, bool* enabled); 285 static bool GetMulticastLoop(intptr_t fd, intptr_t protocol, bool* enabled);
315 static bool SetMulticastLoop(intptr_t fd, intptr_t protocol, bool enabled); 286 static bool SetMulticastLoop(intptr_t fd, intptr_t protocol, bool enabled);
(...skipping 24 matching lines...) Expand all
340 static bool FormatNumericAddress(const RawAddr& addr, char* address, int len); 311 static bool FormatNumericAddress(const RawAddr& addr, char* address, int len);
341 312
342 // Whether ListInterfaces is supported. 313 // Whether ListInterfaces is supported.
343 static bool ListInterfacesSupported(); 314 static bool ListInterfacesSupported();
344 315
345 // List interfaces. Returns a AddressList of InterfaceSocketAddress's. 316 // List interfaces. Returns a AddressList of InterfaceSocketAddress's.
346 static AddressList<InterfaceSocketAddress>* ListInterfaces( 317 static AddressList<InterfaceSocketAddress>* ListInterfaces(
347 int type, 318 int type,
348 OSError** os_error); 319 OSError** os_error);
349 320
350 static CObject* LookupRequest(const CObjectArray& request);
351 static CObject* ListInterfacesRequest(const CObjectArray& request);
352 static CObject* ReverseLookupRequest(const CObjectArray& request);
353
354 static Dart_Port GetServicePort();
355
356 static void SetSocketIdNativeField(Dart_Handle handle,
357 intptr_t id,
358 SocketFinalizer finalizer);
359 static void ReuseSocketIdNativeField(Dart_Handle handle,
360 Socket* socket,
361 SocketFinalizer finalizer);
362 static Socket* GetSocketIdNativeField(Dart_Handle socket);
363
364 private:
365 ~Socket() { ASSERT(fd_ == kClosedFd); }
366
367 static const int kClosedFd = -1;
368
369 intptr_t fd_;
370 Dart_Port port_;
371
372 friend class ReferenceCounted<Socket>;
373 DISALLOW_COPY_AND_ASSIGN(Socket);
374 };
375
376
377 class ServerSocket {
378 public:
379 static const intptr_t kTemporaryFailure = -2;
380
381 static intptr_t Accept(intptr_t fd);
382
383 // Creates a socket which is bound and listens. The port to listen on is
384 // specified in the port component of the passed RawAddr structure.
385 //
386 // Returns a positive integer if the call is successful. In case of failure
387 // it returns:
388 //
389 // -1: system error (errno set)
390 // -5: invalid bindAddress
391 static intptr_t CreateBindListen(const RawAddr& addr,
392 intptr_t backlog,
393 bool v6_only = false);
394
395 // Start accepting on a newly created listening socket. If it was unable to
396 // start accepting incoming sockets, the fd is invalidated.
397 static bool StartAccept(intptr_t fd);
398
399 private: 321 private:
400 DISALLOW_ALLOCATION(); 322 DISALLOW_ALLOCATION();
401 DISALLOW_IMPLICIT_CONSTRUCTORS(ServerSocket); 323 DISALLOW_IMPLICIT_CONSTRUCTORS(SocketBase);
402 };
403
404
405 class ListeningSocketRegistry {
406 public:
407 ListeningSocketRegistry()
408 : sockets_by_port_(SameIntptrValue, kInitialSocketsCount),
409 sockets_by_fd_(SameIntptrValue, kInitialSocketsCount),
410 mutex_(new Mutex()) {}
411
412 ~ListeningSocketRegistry() {
413 CloseAllSafe();
414 delete mutex_;
415 mutex_ = NULL;
416 }
417
418 static void Initialize();
419
420 static ListeningSocketRegistry* Instance();
421
422 static void Cleanup();
423
424 // This function should be called from a dart runtime call in order to create
425 // a new (potentially shared) socket.
426 Dart_Handle CreateBindListen(Dart_Handle socket_object,
427 RawAddr addr,
428 intptr_t backlog,
429 bool v6_only,
430 bool shared);
431
432 // This should be called from the event handler for every kCloseEvent it gets
433 // on listening sockets.
434 //
435 // Returns `true` if the last reference has been dropped and the underlying
436 // socket can be closed.
437 //
438 // The caller is responsible for obtaining the mutex first, before calling
439 // this function.
440 bool CloseSafe(Socket* socketfd);
441
442 Mutex* mutex() { return mutex_; }
443
444 private:
445 struct OSSocket {
446 RawAddr address;
447 int port;
448 bool v6_only;
449 bool shared;
450 int ref_count;
451 Socket* socketfd;
452
453 // Singly linked lists of OSSocket instances which listen on the same port
454 // but on different addresses.
455 OSSocket* next;
456
457 OSSocket(RawAddr address,
458 int port,
459 bool v6_only,
460 bool shared,
461 Socket* socketfd)
462 : address(address),
463 port(port),
464 v6_only(v6_only),
465 shared(shared),
466 ref_count(0),
467 socketfd(socketfd),
468 next(NULL) {}
469 };
470
471 static const intptr_t kInitialSocketsCount = 8;
472
473 OSSocket* FindOSSocketWithAddress(OSSocket* current, const RawAddr& addr) {
474 while (current != NULL) {
475 if (SocketAddress::AreAddressesEqual(current->address, addr)) {
476 return current;
477 }
478 current = current->next;
479 }
480 return NULL;
481 }
482
483 static bool SameIntptrValue(void* key1, void* key2) {
484 return reinterpret_cast<intptr_t>(key1) == reinterpret_cast<intptr_t>(key2);
485 }
486
487 static uint32_t GetHashmapHashFromIntptr(intptr_t i) {
488 return static_cast<uint32_t>((i + 1) & 0xFFFFFFFF);
489 }
490
491
492 static void* GetHashmapKeyFromIntptr(intptr_t i) {
493 return reinterpret_cast<void*>(i + 1);
494 }
495
496 OSSocket* LookupByPort(intptr_t port);
497 void InsertByPort(intptr_t port, OSSocket* socket);
498 void RemoveByPort(intptr_t port);
499
500 OSSocket* LookupByFd(Socket* fd);
501 void InsertByFd(Socket* fd, OSSocket* socket);
502 void RemoveByFd(Socket* fd);
503
504 bool CloseOneSafe(OSSocket* os_socket, bool update_hash_maps);
505 void CloseAllSafe();
506
507 HashMap sockets_by_port_;
508 HashMap sockets_by_fd_;
509
510 Mutex* mutex_;
511
512 DISALLOW_COPY_AND_ASSIGN(ListeningSocketRegistry);
513 }; 324 };
514 325
515 } // namespace bin 326 } // namespace bin
516 } // namespace dart 327 } // namespace dart
517 328
518 #endif // RUNTIME_BIN_SOCKET_H_ 329 #endif // RUNTIME_BIN_SOCKET_BASE_H_
OLDNEW
« no previous file with comments | « runtime/bin/socket_android.cc ('k') | runtime/bin/socket_base.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698