[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();