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