about summary refs log tree commit diff
diff options
context:
space:
mode:
authorChristiaan Dirkx <christiaan@dirkx.email>2021-05-24 23:58:20 +0200
committerSimonas Kazlauskas <git@kazlauskas.me>2021-10-02 22:08:35 +0300
commit9a6f2e655aa15bd600fc55949b17bbc51fc1565d (patch)
tree26e9c7600a1f65e73e661470d988147c1f2d39c4
parentd14731cb3ced8318d7fc83cbe838f0e7f2fb3b40 (diff)
downloadrust-9a6f2e655aa15bd600fc55949b17bbc51fc1565d.tar.gz
rust-9a6f2e655aa15bd600fc55949b17bbc51fc1565d.zip
Only register `WSACleanup` if `WSAStartup` is actually ever called
-rw-r--r--library/std/src/sys/windows/net.rs17
1 files changed, 11 insertions, 6 deletions
diff --git a/library/std/src/sys/windows/net.rs b/library/std/src/sys/windows/net.rs
index 33152cc97ab..84a5a389e0d 100644
--- a/library/std/src/sys/windows/net.rs
+++ b/library/std/src/sys/windows/net.rs
@@ -2,13 +2,13 @@
 
 use crate::cmp;
 use crate::io::{self, IoSlice, IoSliceMut, Read};
+use crate::lazy::SyncOnceCell;
 use crate::mem;
 use crate::net::{Shutdown, SocketAddr};
 use crate::os::windows::io::{
     AsRawSocket, AsSocket, BorrowedSocket, FromRawSocket, IntoRawSocket, OwnedSocket, RawSocket,
 };
 use crate::ptr;
-use crate::sync::Once;
 use crate::sys;
 use crate::sys::c;
 use crate::sys_common::net;
@@ -29,26 +29,31 @@ pub mod netc {
 
 pub struct Socket(OwnedSocket);
 
-static INIT: Once = Once::new();
+static WSA: SyncOnceCell<unsafe extern "system" fn() -> i32> = SyncOnceCell::new();
 
 /// Checks whether the Windows socket interface has been started already, and
 /// if not, starts it.
 pub fn init() {
-    INIT.call_once(|| unsafe {
+    let _ = WSA.get_or_init(|| unsafe {
         let mut data: c::WSADATA = mem::zeroed();
         let ret = c::WSAStartup(
             0x202, // version 2.2
             &mut data,
         );
         assert_eq!(ret, 0);
+
+        // Only register `WSACleanup` if `WSAStartup` is actually ever called.
+        // Workaround to prevent linking to `WS2_32.dll` when no network functionality is used.
+        // See issue #85441.
+        c::WSACleanup
     });
 }
 
 pub fn cleanup() {
-    if INIT.is_completed() {
-        // only close the socket interface if it has actually been started
+    // only perform cleanup if network functionality was actually initialized
+    if let Some(cleanup) = WSA.get() {
         unsafe {
-            c::WSACleanup();
+            cleanup();
         }
     }
 }