[io/socket] Make Socket::fd_ atomic since it can get updated from multiple threads.

Follow-up to https://dart.googlesource.com/sdk/+/ba7aaa929f579aaa55a2fc09a098f81df6b27804, sink the "is fd closed" check to avoid multiple reads.

Fixes https://github.com/dart-lang/sdk/issues/61582
TEST=ci

Change-Id: Id00cd8ad8b7831006ad47c665ac09eb9f38fa6f9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/451600
Reviewed-by: Tess Strickland <sstrickl@google.com>
Commit-Queue: Alexander Aprelev <aam@google.com>
diff --git a/runtime/bin/socket.cc b/runtime/bin/socket.cc
index 1d14d42..0de173f 100644
--- a/runtime/bin/socket.cc
+++ b/runtime/bin/socket.cc
@@ -953,11 +953,6 @@
 void FUNCTION_NAME(Socket_GetType)(Dart_NativeArguments args) {
   Socket* socket =
       Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
-  if (socket->fd() < 0) {
-    OSError os_error(-1, "Socket is closed.", OSError::kUnknown);
-    Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
-    return;
-  }
   OSError os_error;
   intptr_t type = SocketBase::GetType(socket->fd());
   if (type >= 0) {
diff --git a/runtime/bin/socket.h b/runtime/bin/socket.h
index 9a53d51..a5a998a 100644
--- a/runtime/bin/socket.h
+++ b/runtime/bin/socket.h
@@ -124,7 +124,7 @@
   static bool short_socket_read_;
   static bool short_socket_write_;
 
-  intptr_t fd_;
+  std::atomic<intptr_t> fd_;
   Dart_Port isolate_port_;
   Dart_Port port_;
   uint8_t* udp_receive_buffer_;
diff --git a/runtime/bin/socket_base_win.cc b/runtime/bin/socket_base_win.cc
index 966dada..25c40ca 100644
--- a/runtime/bin/socket_base_win.cc
+++ b/runtime/bin/socket_base_win.cc
@@ -215,6 +215,10 @@
 }
 
 int SocketBase::GetType(intptr_t fd) {
+  if (fd < 0) {
+    return -1;
+  }
+
   Handle* handle = reinterpret_cast<Handle*>(fd);
   switch (GetFileType(handle->handle())) {
     case FILE_TYPE_CHAR:
diff --git a/runtime/bin/socket_win.cc b/runtime/bin/socket_win.cc
index a64dcee..fbb5bb6 100644
--- a/runtime/bin/socket_win.cc
+++ b/runtime/bin/socket_win.cc
@@ -26,13 +26,15 @@
       port_(ILLEGAL_PORT),
       udp_receive_buffer_(nullptr) {
   ASSERT(fd_ != kClosedFd);
-  Handle* handle = reinterpret_cast<Handle*>(fd_);
+  intptr_t fd_handle = fd_;
+  Handle* handle = reinterpret_cast<Handle*>(fd_handle);
   ASSERT(handle != nullptr);
 }
 
 void Socket::CloseFd() {
-  ASSERT(fd_ != kClosedFd);
-  Handle* handle = reinterpret_cast<Handle*>(fd_);
+  intptr_t fd_handle = fd();
+  ASSERT(fd_handle != kClosedFd);
+  Handle* handle = reinterpret_cast<Handle*>(fd_handle);
   ASSERT(handle != nullptr);
   handle->Release();
   SetClosedFd();