• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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::io::{ErrorKind, Read};
15 
16 use ylong_io::{Interest, UnixStream};
17 
18 #[cfg(not(feature = "ffrt"))]
19 use crate::executor::driver::Handle;
20 use crate::net::driver::SIGNAL_TOKEN;
21 use crate::signal::unix::registry::Registry;
22 
23 pub(crate) struct SignalDriver {
24     receiver: UnixStream,
25 }
26 
27 cfg_ffrt! {
28     use std::mem::MaybeUninit;
29     static mut SIGNAL_DRIVER: MaybeUninit<SignalDriver> = MaybeUninit::uninit();
30 }
31 
32 impl SignalDriver {
broadcast(&mut self)33     pub(crate) fn broadcast(&mut self) {
34         let mut buf = [0_u8; 8];
35         loop {
36             match self.receiver.read(&mut buf) {
37                 Ok(0) => panic!("EOF occurs in signal stream"),
38                 Ok(_) => {}
39                 Err(e) if e.kind() == ErrorKind::WouldBlock => break,
40                 Err(e) => panic!("Error occurs in signal stream: {e}"),
41             }
42         }
43         Registry::get_instance().broadcast();
44     }
45 }
46 
47 #[cfg(not(feature = "ffrt"))]
48 impl SignalDriver {
initialize(handle: &Handle) -> SignalDriver49     pub(crate) fn initialize(handle: &Handle) -> SignalDriver {
50         // panic will occur when some errors like fds reaches the maximum limit
51         // or insufficient memory occur. For more detailed errors, please refer to
52         // `libc::fcntl`.
53         let mut receiver = Registry::get_instance()
54             .try_clone_stream()
55             .unwrap_or_else(|e| panic!("Signal failed to clone UnixStream, {e}"));
56         let _ = handle.io_register_with_token(
57             &mut receiver,
58             SIGNAL_TOKEN,
59             Interest::READABLE | Interest::WRITABLE,
60         );
61         SignalDriver { receiver }
62     }
63 }
64 
65 #[cfg(feature = "ffrt")]
66 impl SignalDriver {
get_mut_ref() -> &'static mut Self67     pub(crate) fn get_mut_ref() -> &'static mut Self {
68         SignalDriver::initialize();
69         unsafe { &mut *SIGNAL_DRIVER.as_mut_ptr() }
70     }
71 
initialize()72     pub(crate) fn initialize() {
73         static ONCE: std::sync::Once = std::sync::Once::new();
74         ONCE.call_once(|| unsafe {
75             let mut receiver = Registry::get_instance()
76                 .try_clone_stream()
77                 .unwrap_or_else(|e| panic!("Signal failed to clone UnixStream, {e}"));
78             let inner = crate::net::IoHandle::get_ref();
79             inner.register_source_with_token(
80                 &mut receiver,
81                 SIGNAL_TOKEN,
82                 Interest::READABLE | Interest::WRITABLE,
83             );
84             SIGNAL_DRIVER = MaybeUninit::new(SignalDriver { receiver });
85         });
86     }
87 }
88