@@ -8,7 +8,8 @@ use crate::net::{Shutdown, SocketAddr};
88use  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 } ; 
1213use  crate :: sys:: c; 
1314use  crate :: sys_common:: { AsInner ,  FromInner ,  IntoInner } ; 
1415use  crate :: time:: Duration ; 
@@ -114,33 +115,38 @@ pub(super) mod netc {
114115#[ expect( missing_debug_implementations) ]  
115116pub  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]  
121123pub  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
137146pub  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