@@ -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,35 +115,36 @@ 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-     } ) ; 
135- } 
136- 
137- 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 ( ) ; 
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 ( ) ; 
142142        } 
143143    } 
144144} 
145145
146+ pub  fn  cleanup ( )  { } 
147+ 
146148/// Returns the last error from the Windows socket interface. 
147149fn  last_error ( )  -> io:: Error  { 
148150    io:: Error :: from_raw_os_error ( unsafe  {  c:: WSAGetLastError ( )  } ) 
0 commit comments