1 // Copyright (c) 2023 Huawei Device Co., Ltd.
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 //     http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 use std::os::windows::io::RawSocket;
15 use std::pin::Pin;
16 use std::sync::{Arc, Mutex, Once};
17 use std::{io, net};
18 
19 use crate::sys::windows::selector::{SelectorInner, SockState};
20 use crate::{Interest, Selector, Token};
21 
22 /// Initialise the network stack for Windows.
init()23 pub(crate) fn init() {
24     static INIT: Once = Once::new();
25     INIT.call_once(|| {
26         drop(net::UdpSocket::bind("127.0.0.1:0"));
27     });
28 }
29 
30 #[derive(Clone)]
31 pub(crate) struct NetState {
32     /// State is None if the socket has not been Registered.
33     inner: Option<Box<NetInner>>,
34 }
35 
36 impl NetState {
37     /// Creates a new `NetState` with None.
new() -> NetState38     pub(crate) fn new() -> NetState {
39         NetState { inner: None }
40     }
41 
42     /// Register the socket to [`Selector`]
43     /// If inner is Some, this function returns Err(AlreadyExists).
44     /// If register success, Set the inner to Some.
register( &mut self, selector: &Selector, token: Token, interests: Interest, socket: RawSocket, ) -> io::Result<()>45     pub fn register(
46         &mut self,
47         selector: &Selector,
48         token: Token,
49         interests: Interest,
50         socket: RawSocket,
51     ) -> io::Result<()> {
52         match self.inner {
53             Some(_) => Err(io::ErrorKind::AlreadyExists.into()),
54             None => selector.register(socket, token, interests).map(|state| {
55                 self.inner = Some(Box::new(state));
56             }),
57         }
58     }
59 
60     /// Deregister the socket
deregister(&mut self) -> io::Result<()>61     pub fn deregister(&mut self) -> io::Result<()> {
62         match self.inner.as_mut() {
63             Some(state) => {
64                 {
65                     let mut sock_state = state.state.lock().unwrap();
66                     sock_state.start_drop();
67                 }
68                 self.inner = None;
69                 Ok(())
70             }
71             None => Err(io::ErrorKind::NotFound.into()),
72         }
73     }
74 
75     /// The IO operation does not really report an error when Err(WouldBlock)
76     /// occurs. We need to re-register the current IO operation.
try_io<T, F, R>(&self, task: F, io: &T) -> io::Result<R> where F: FnOnce(&T) -> io::Result<R>,77     pub(crate) fn try_io<T, F, R>(&self, task: F, io: &T) -> io::Result<R>
78     where
79         F: FnOnce(&T) -> io::Result<R>,
80     {
81         let result = task(io);
82         if let Err(ref e) = result {
83             if e.kind() == io::ErrorKind::WouldBlock {
84                 self.inner.as_ref().map_or(Ok(()), |net_inner| {
85                     net_inner.selector.reregister(
86                         net_inner.state.clone(),
87                         net_inner.token,
88                         net_inner.interests,
89                     )
90                 })?;
91             }
92         }
93         result
94     }
95 }
96 
97 /// This structure used to re-register the socket when Err(WouldBlock) occurs
98 #[derive(Clone)]
99 pub(crate) struct NetInner {
100     selector: Arc<SelectorInner>,
101     token: Token,
102     interests: Interest,
103     state: Pin<Arc<Mutex<SockState>>>,
104 }
105 
106 impl NetInner {
new( selector: Arc<SelectorInner>, token: Token, interests: Interest, state: Pin<Arc<Mutex<SockState>>>, ) -> NetInner107     pub(crate) fn new(
108         selector: Arc<SelectorInner>,
109         token: Token,
110         interests: Interest,
111         state: Pin<Arc<Mutex<SockState>>>,
112     ) -> NetInner {
113         NetInner {
114             selector,
115             token,
116             interests,
117             state,
118         }
119     }
120 }
121 
122 impl Drop for NetInner {
drop(&mut self)123     fn drop(&mut self) {
124         let mut sock_state = self.state.lock().unwrap();
125         sock_state.start_drop();
126     }
127 }
128