Untitled

 avatar
unknown
plain_text
2 years ago
2.0 kB
4
Indexable
pub mod single_thread_executor {
        use std::error::Error;
        use std::fmt::{Display, Formatter};
        use std::sync::mpsc::{channel, Sender};
        use std::sync::Mutex;
        use std::thread;
        use std::thread::JoinHandle;

        #[derive(Debug, Clone)]
        pub struct ExecutorError {
            msg: String,
        }

        impl ExecutorError {
            pub fn new(msg: &str) -> Self {
                ExecutorError{msg: msg.to_string()}
            }
        }

        impl Display for ExecutorError {
            fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
                write!(f, "{}", self.msg)
            }
        }

        impl Error for ExecutorError {}

        enum State {
            Stop,
            Run
        }

        pub struct SingleThreadExecutor {
            tx: Sender<Box<dyn Fn() + Send + 'static>>,
            thread: JoinHandle<()>,
            state: Mutex<State>,
        }

        impl SingleThreadExecutor {
            pub fn new() -> Self {
                let (tx, rx) = channel::<Box<dyn Fn() + Send + 'static>>();
                let thread = thread::spawn(move || {
                    while let Ok(task) = rx.recv() {
                        (*task)();
                    }
                });
                SingleThreadExecutor{ tx, thread, state: Mutex::new(State::Run) }
            }

            pub fn submit(&self, f: Box<dyn Fn() + Send + 'static>) -> Result<(), ExecutorError> {
                match *self.state.lock().unwrap() {
                    State::Run => { self.tx.send(f).unwrap(); Ok(()) },
                    State::Stop => Err(ExecutorError::new("Single thread executor closed.")),
                }
            }

            pub fn close(&self) {
                *self.state.lock().unwrap() = State::Stop;
            }

            pub fn join(self) {
                self.close();
                self.thread.join().unwrap();
            }
        }
Editor is loading...