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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
use priv_prelude::*;
use future_utils;
use std;

/// A `Network` manages a set of tasks/devices. Dropping the `Network` will destroy all associated
/// tasks/devices.
pub struct Network {
    handle: Handle,
    drop_tx_tx: std::sync::mpsc::Sender<DropNotify>,
    _drop_tx_rx: std::sync::mpsc::Receiver<DropNotify>,
}

impl Network {
    /// Create a new `Network` running on the given event loop.
    pub fn new(handle: &Handle) -> Network {
        let (drop_tx_tx, drop_tx_rx) = std::sync::mpsc::channel();
        Network {
            handle: handle.clone(),
            drop_tx_tx: drop_tx_tx,
            _drop_tx_rx: drop_tx_rx,
        }
    }

    /// Get a handle to the network. Can be used to spawn tasks to the network.
    pub fn handle(&self) -> NetworkHandle {
        NetworkHandle {
            handle: self.handle.clone(),
            drop_tx_tx: self.drop_tx_tx.clone(),
        }
    }
}

#[derive(Clone)]
/// A handle to a `Network`
pub struct NetworkHandle {
    handle: Handle,
    drop_tx_tx: std::sync::mpsc::Sender<DropNotify>,
}

impl NetworkHandle {
    /// Get a copy of the event loop handle
    pub fn event_loop(&self) -> &Handle {
        &self.handle
    }

    /// Spawn a future to the event loop. The future will be cancelled when the `Network` is
    /// destroyed,
    pub fn spawn<F>(&self, f: F)
    where
        F: Future<Item = (), Error = Void> + 'static,
    {
        let (drop_tx, drop_rx) = future_utils::drop_notify();
        if self.drop_tx_tx.send(drop_tx).is_err() {
            panic!("network has been destroyed");
        }

        self.handle.spawn({
            f
            .until(drop_rx)
            .map(|_unit_opt| ())
            .infallible()
        });
    }
}