summaryrefslogtreecommitdiffhomepage
path: root/mullvad-daemon/src/event_loop.rs
blob: 58f638a2aca122950cfce3764ae42255ba0df43e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
use futures01::{sync::oneshot, Future};
use std::thread;
use tokio_core::reactor::{Core, Remote};

pub struct CoreHandle {
    /// Remote used to spawn futures on the daemon's event loop.
    pub remote: Remote,
    /// A sender that will cause the event loop to stop once it's dropped.
    shutdown_tx: Option<oneshot::Sender<()>>,
}

impl Drop for CoreHandle {
    fn drop(&mut self) {
        if let Some(shutdown_tx) = self.shutdown_tx.take() {
            if shutdown_tx.send(()).is_err() {
                log::error!("Core already shut down");
            }
        }
    }
}

/// Panics if a new tokio event loop can't be spawned.
pub fn spawn() -> CoreHandle {
    let (tx, rx) = oneshot::channel();
    let (shutdown_tx, shutdown_rx) = oneshot::channel();
    thread::spawn(move || {
        let mut core = Core::new().expect("Failed to spawn event loop");
        let remote = core.remote();
        let _ = tx.send(remote);
        let _ = core.run(shutdown_rx);
    });
    let remote = rx.wait().expect("Failed to spawn event loop");

    CoreHandle {
        remote,
        shutdown_tx: Some(shutdown_tx),
    }
}