Skip to content

Commit c8fb37a

Browse files
committed
Don't call WSACleanup on process exit
1 parent 64b185e commit c8fb37a

File tree

1 file changed

+21
-15
lines changed
  • library/std/src/sys/net/connection/socket

1 file changed

+21
-15
lines changed

library/std/src/sys/net/connection/socket/windows.rs

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ use crate::net::{Shutdown, SocketAddr};
88
use crate::os::windows::io::{
99
AsRawSocket, AsSocket, BorrowedSocket, FromRawSocket, IntoRawSocket, OwnedSocket, RawSocket,
1010
};
11-
use crate::sync::OnceLock;
11+
use crate::sync::atomic::Atomic;
12+
use crate::sync::atomic::Ordering::{AcqRel, Relaxed};
1213
use crate::sys::c;
1314
use crate::sys_common::{AsInner, FromInner, IntoInner};
1415
use crate::time::Duration;
@@ -114,33 +115,38 @@ pub(super) mod netc {
114115
#[expect(missing_debug_implementations)]
115116
pub struct Socket(OwnedSocket);
116117

117-
static WSA_CLEANUP: OnceLock<unsafe extern "system" fn() -> i32> = OnceLock::new();
118+
static WSA_INITIALIZED: Atomic<bool> = Atomic::<bool>::new(false);
118119

119120
/// Checks whether the Windows socket interface has been started already, and
120121
/// if not, starts it.
122+
#[inline]
121123
pub fn init() {
122-
let _ = WSA_CLEANUP.get_or_init(|| unsafe {
124+
if !WSA_INITIALIZED.load(Relaxed) {
125+
wsa_startup();
126+
}
127+
}
128+
129+
#[cold]
130+
fn wsa_startup() {
131+
unsafe {
123132
let mut data: c::WSADATA = mem::zeroed();
124133
let ret = c::WSAStartup(
125134
0x202, // version 2.2
126135
&mut data,
127136
);
128137
assert_eq!(ret, 0);
129-
130-
// Only register `WSACleanup` if `WSAStartup` is actually ever called.
131-
// Workaround to prevent linking to `WS2_32.dll` when no network functionality is used.
132-
// See issue #85441.
133-
c::WSACleanup
134-
});
138+
if WSA_INITIALIZED.swap(true, AcqRel) {
139+
// If another thread raced with us and called WSAStartup first then call
140+
// WSACleanup so it's as though WSAStartup was only called once.
141+
c::WSACleanup();
142+
}
143+
}
135144
}
136145

137146
pub fn cleanup() {
138-
// only perform cleanup if network functionality was actually initialized
139-
if let Some(cleanup) = WSA_CLEANUP.get() {
140-
unsafe {
141-
cleanup();
142-
}
143-
}
147+
// We don't need to call WSACleanup here because exiting the process will cause
148+
// the OS to clean everything for us, which is faster than doing it manually.
149+
// See #141799.
144150
}
145151

146152
/// Returns the last error from the Windows socket interface.

0 commit comments

Comments
 (0)