std\sys\pal\windows/
winsock.rs1use super::c;
2use crate::ffi::c_int;
3use crate::sync::atomic::Atomic;
4use crate::sync::atomic::Ordering::{AcqRel, Relaxed};
5use crate::{io, mem};
6
7static WSA_STARTED: Atomic<bool> = Atomic::<bool>::new(false);
8
9#[inline]
12pub fn startup() {
13 if !WSA_STARTED.load(Relaxed) {
14 wsa_startup();
15 }
16}
17
18#[cold]
19fn wsa_startup() {
20 unsafe {
21 let mut data: c::WSADATA = mem::zeroed();
22 let ret = c::WSAStartup(
23 0x202, &mut data,
25 );
26 assert_eq!(ret, 0);
27 if WSA_STARTED.swap(true, AcqRel) {
28 c::WSACleanup();
31 }
32 }
33}
34
35pub fn cleanup() {
36 }
40
41pub fn last_error() -> io::Error {
43 io::Error::from_raw_os_error(unsafe { c::WSAGetLastError() })
44}
45
46#[doc(hidden)]
47pub trait IsMinusOne {
48 fn is_minus_one(&self) -> bool;
49}
50
51macro_rules! impl_is_minus_one {
52 ($($t:ident)*) => ($(impl IsMinusOne for $t {
53 fn is_minus_one(&self) -> bool {
54 *self == -1
55 }
56 })*)
57}
58
59impl_is_minus_one! { i8 i16 i32 i64 isize }
60
61pub fn cvt<T: IsMinusOne>(t: T) -> io::Result<T> {
65 if t.is_minus_one() { Err(last_error()) } else { Ok(t) }
66}
67
68pub fn cvt_gai(err: c_int) -> io::Result<()> {
70 if err == 0 { Ok(()) } else { Err(last_error()) }
71}
72
73pub fn cvt_r<T, F>(mut f: F) -> io::Result<T>
75where
76 T: IsMinusOne,
77 F: FnMut() -> T,
78{
79 cvt(f())
80}