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