cdp_html_shot/
exit_hook.rs

1use std::panic;
2use std::sync::{Arc, Once};
3
4/// A struct that manages cleanup functions to be executed on process termination.
5pub struct ExitHook {
6    cleanup_fn: Arc<dyn Fn() + Send + Sync + 'static>,
7}
8
9impl ExitHook {
10    /**
11    Creates a new ExitHook with the given cleanup function.
12
13    # Arguments
14
15    * `f` - A function to be executed when the process exits
16
17    # Example
18
19    ```rust
20    use cdp_html_shot::ExitHook;
21    let hook = ExitHook::new(|| println!("Cleaning up..."));
22
23    hook.register().unwrap();
24    ```
25    */
26    pub fn new<F>(f: F) -> Self
27    where
28        F: Fn() + Send + Sync + 'static
29    {
30        ExitHook {
31            cleanup_fn: Arc::new(f),
32        }
33    }
34
35    /// Registers all necessary hooks for process termination.
36    pub fn register(&self) -> Result<(), Box<dyn std::error::Error>> {
37        static INIT: Once = Once::new();
38        let cleanup_fn = Arc::clone(&self.cleanup_fn);
39
40        // Set up panic hook
41        let original_hook = panic::take_hook();
42        let panic_cleanup_fn = Arc::clone(&cleanup_fn);
43        panic::set_hook(Box::new(move |panic_info| {
44            panic_cleanup_fn();
45            original_hook(panic_info);
46        }));
47
48        // Set up Ctrl+C handler
49        INIT.call_once(|| {
50            let ctrl_c_cleanup_fn = Arc::clone(&cleanup_fn);
51            if let Err(e) = ctrlc::set_handler(move || {
52                ctrl_c_cleanup_fn();
53                std::process::exit(0);
54            }) {
55                eprintln!("Error setting Ctrl-C handler: {}", e);
56            }
57        });
58
59        Ok(())
60    }
61}
62
63impl Drop for ExitHook {
64    fn drop(&mut self) {
65        (self.cleanup_fn)();
66    }
67}