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

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

Issue 2780063002: Pulled a significant portion of Socket implementation into BaseSocket in order to prepare for the s… (Closed)
Patch Set: Addressed comments, re-added socket_unsupported.cc 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_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(TARGET_OS_ANDROID)
zra 2017/04/03 03:40:23 I think these should probably still be HOST_OS_*
rmacnak 2017/04/03 16:03:55 Right, HOST_OS. Only the AOT compiler should be us
bkonyi 2017/04/03 16:09:57 Good to know! I don't know why/how these were chan
15 #include "bin/socket_android.h" 15 #include "bin/socket_base_android.h"
16 #elif defined(HOST_OS_FUCHSIA) 16 #elif defined(TARGET_OS_FUCHSIA)
17 #include "bin/socket_fuchsia.h" 17 #include "bin/socket_base_fuchsia.h"
18 #elif defined(HOST_OS_LINUX) 18 #elif defined(TARGET_OS_LINUX)
19 #include "bin/socket_linux.h" 19 #include "bin/socket_base_linux.h"
20 #elif defined(HOST_OS_MACOS) 20 #elif defined(TARGET_OS_MACOS)
21 #include "bin/socket_macos.h" 21 #include "bin/socket_base_macos.h"
22 #elif defined(HOST_OS_WINDOWS) 22 #elif defined(TARGET_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 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 // TODO(dart:io): Convert these to instance methods where possible.
272 static bool Initialize();
273 static intptr_t Available(intptr_t fd); 259 static intptr_t Available(intptr_t fd);
274 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);
275 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);
276 // 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
277 // component of the passed RawAddr structure. The RawAddr structure is only 263 // component of the passed RawAddr structure. The RawAddr structure is only
278 // used for datagram sockets. 264 // used for datagram sockets.
279 static intptr_t SendTo(intptr_t fd, 265 static intptr_t SendTo(intptr_t fd,
280 const void* buffer, 266 const void* buffer,
281 intptr_t num_bytes, 267 intptr_t num_bytes,
282 const RawAddr& addr); 268 const RawAddr& addr);
283 static intptr_t RecvFrom(intptr_t fd, 269 static intptr_t RecvFrom(intptr_t fd,
284 void* buffer, 270 void* buffer,
285 intptr_t num_bytes, 271 intptr_t num_bytes,
286 RawAddr* addr); 272 RawAddr* addr);
287 // Creates a socket which is bound and connected. The port to connect to is
288 // specified as the port component of the passed RawAddr structure.
289 static intptr_t CreateConnect(const RawAddr& addr);
290 // Creates a socket which is bound and connected. The port to connect to is
291 // specified as the port component of the passed RawAddr structure.
292 static intptr_t CreateBindConnect(const RawAddr& addr,
293 const RawAddr& source_addr);
294 // 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
295 // to bind the socket to a specific IP. 274 // to bind the socket to a specific IP.
296 static bool IsBindError(intptr_t error_number); 275 static bool IsBindError(intptr_t error_number);
297 // Creates a datagram socket which is bound. The port to bind
298 // to is specified as the port component of the RawAddr structure.
299 static intptr_t CreateBindDatagram(const RawAddr& addr, bool reuseAddress);
300 static intptr_t GetPort(intptr_t fd); 276 static intptr_t GetPort(intptr_t fd);
301 static SocketAddress* GetRemotePeer(intptr_t fd, intptr_t* port); 277 static SocketAddress* GetRemotePeer(intptr_t fd, intptr_t* port);
302 static void GetError(intptr_t fd, OSError* os_error); 278 static void GetError(intptr_t fd, OSError* os_error);
303 static int GetType(intptr_t fd); 279 static int GetType(intptr_t fd);
304 static intptr_t GetStdioHandle(intptr_t num); 280 static intptr_t GetStdioHandle(intptr_t num);
305 static void Close(intptr_t fd); 281 static void Close(intptr_t fd);
306 static bool GetNoDelay(intptr_t fd, bool* enabled); 282 static bool GetNoDelay(intptr_t fd, bool* enabled);
307 static bool SetNoDelay(intptr_t fd, bool enabled); 283 static bool SetNoDelay(intptr_t fd, bool enabled);
308 static bool GetMulticastLoop(intptr_t fd, intptr_t protocol, bool* enabled); 284 static bool GetMulticastLoop(intptr_t fd, intptr_t protocol, bool* enabled);
309 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
334 static bool FormatNumericAddress(const RawAddr& addr, char* address, int len); 310 static bool FormatNumericAddress(const RawAddr& addr, char* address, int len);
335 311
336 // Whether ListInterfaces is supported. 312 // Whether ListInterfaces is supported.
337 static bool ListInterfacesSupported(); 313 static bool ListInterfacesSupported();
338 314
339 // List interfaces. Returns a AddressList of InterfaceSocketAddress's. 315 // List interfaces. Returns a AddressList of InterfaceSocketAddress's.
340 static AddressList<InterfaceSocketAddress>* ListInterfaces( 316 static AddressList<InterfaceSocketAddress>* ListInterfaces(
341 int type, 317 int type,
342 OSError** os_error); 318 OSError** os_error);
343 319
344 static CObject* LookupRequest(const CObjectArray& request);
345 static CObject* ListInterfacesRequest(const CObjectArray& request);
346 static CObject* ReverseLookupRequest(const CObjectArray& request);
347
348 static Dart_Port GetServicePort();
349
350 static void SetSocketIdNativeField(Dart_Handle handle,
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);
357
358 private:
359 ~Socket() { ASSERT(fd_ == kClosedFd); }
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);
368 };
369
370
371 class ServerSocket {
372 public:
373 static const intptr_t kTemporaryFailure = -2;
374
375 static intptr_t Accept(intptr_t fd);
376
377 // Creates a socket which is bound and listens. The port to listen on is
378 // specified in the port component of the passed RawAddr structure.
379 //
380 // Returns a positive integer if the call is successful. In case of failure
381 // it returns:
382 //
383 // -1: system error (errno set)
384 // -5: invalid bindAddress
385 static intptr_t CreateBindListen(const RawAddr& addr,
386 intptr_t backlog,
387 bool v6_only = false);
388
389 // Start accepting on a newly created listening socket. If it was unable to
390 // start accepting incoming sockets, the fd is invalidated.
391 static bool StartAccept(intptr_t fd);
392
393 private: 320 private:
394 DISALLOW_ALLOCATION(); 321 DISALLOW_ALLOCATION();
395 DISALLOW_IMPLICIT_CONSTRUCTORS(ServerSocket); 322 DISALLOW_IMPLICIT_CONSTRUCTORS(SocketBase);
396 };
397
398
399 class ListeningSocketRegistry {
400 public:
401 ListeningSocketRegistry()
402 : sockets_by_port_(SameIntptrValue, kInitialSocketsCount),
403 sockets_by_fd_(SameIntptrValue, kInitialSocketsCount),
404 mutex_(new Mutex()) {}
405
406 ~ListeningSocketRegistry() {
407 CloseAllSafe();
408 delete mutex_;
409 mutex_ = NULL;
410 }
411
412 static void Initialize();
413
414 static ListeningSocketRegistry* Instance();
415
416 static void Cleanup();
417
418 // This function should be called from a dart runtime call in order to create
419 // a new (potentially shared) socket.
420 Dart_Handle CreateBindListen(Dart_Handle socket_object,
421 RawAddr addr,
422 intptr_t backlog,
423 bool v6_only,
424 bool shared);
425
426 // This should be called from the event handler for every kCloseEvent it gets
427 // on listening sockets.
428 //
429 // Returns `true` if the last reference has been dropped and the underlying
430 // socket can be closed.
431 //
432 // The caller is responsible for obtaining the mutex first, before calling
433 // this function.
434 bool CloseSafe(Socket* socketfd);
435
436 Mutex* mutex() { return mutex_; }
437
438 private:
439 struct OSSocket {
440 RawAddr address;
441 int port;
442 bool v6_only;
443 bool shared;
444 int ref_count;
445 Socket* socketfd;
446
447 // Singly linked lists of OSSocket instances which listen on the same port
448 // but on different addresses.
449 OSSocket* next;
450
451 OSSocket(RawAddr address,
452 int port,
453 bool v6_only,
454 bool shared,
455 Socket* socketfd)
456 : address(address),
457 port(port),
458 v6_only(v6_only),
459 shared(shared),
460 ref_count(0),
461 socketfd(socketfd),
462 next(NULL) {}
463 };
464
465 static const intptr_t kInitialSocketsCount = 8;
466
467 OSSocket* FindOSSocketWithAddress(OSSocket* current, const RawAddr& addr) {
468 while (current != NULL) {
469 if (SocketAddress::AreAddressesEqual(current->address, addr)) {
470 return current;
471 }
472 current = current->next;
473 }
474 return NULL;
475 }
476
477 static bool SameIntptrValue(void* key1, void* key2) {
478 return reinterpret_cast<intptr_t>(key1) == reinterpret_cast<intptr_t>(key2);
479 }
480
481 static uint32_t GetHashmapHashFromIntptr(intptr_t i) {
482 return static_cast<uint32_t>((i + 1) & 0xFFFFFFFF);
483 }
484
485
486 static void* GetHashmapKeyFromIntptr(intptr_t i) {
487 return reinterpret_cast<void*>(i + 1);
488 }
489
490 OSSocket* LookupByPort(intptr_t port);
491 void InsertByPort(intptr_t port, OSSocket* socket);
492 void RemoveByPort(intptr_t port);
493
494 OSSocket* LookupByFd(Socket* fd);
495 void InsertByFd(Socket* fd, OSSocket* socket);
496 void RemoveByFd(Socket* fd);
497
498 bool CloseOneSafe(OSSocket* os_socket, bool update_hash_maps);
499 void CloseAllSafe();
500
501 HashMap sockets_by_port_;
502 HashMap sockets_by_fd_;
503
504 Mutex* mutex_;
505
506 DISALLOW_COPY_AND_ASSIGN(ListeningSocketRegistry);
507 }; 323 };
508 324
509 } // namespace bin 325 } // namespace bin
510 } // namespace dart 326 } // namespace dart
511 327
512 #endif // RUNTIME_BIN_SOCKET_H_ 328 #endif // RUNTIME_BIN_SOCKET_BASE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698