637 changes: 317 additions & 320 deletions src/unix.rs

Large diffs are not rendered by default.

41 changes: 21 additions & 20 deletions src/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@ extern crate winapi;
use std::cell::RefCell;
use std::io;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Once, ONCE_INIT, Mutex};
use std::sync::{Once, ONCE_INIT};

use futures::stream::{Stream, Fuse};
use futures::{self, Future, IntoFuture, Complete, Oneshot, Poll, Async};
use futures::future;
use futures::stream::Fuse;
use futures::sync::mpsc;
use futures::sync::oneshot;
use futures::{Future, IntoFuture, Poll, Async, Stream};
use tokio_core::io::IoFuture;
use tokio_core::reactor::{PollEvented, Handle};
use tokio_core::channel::{channel, Sender, Receiver};

static INIT: Once = ONCE_INIT;
static mut GLOBAL_STATE: *mut GlobalState = 0 as *mut _;
Expand All @@ -40,12 +42,12 @@ static mut GLOBAL_STATE: *mut GlobalState = 0 as *mut _;
/// two notifications.
pub struct Event {
reg: PollEvented<MyRegistration>,
_finished: Complete<()>,
_finished: oneshot::Sender<()>,
}

struct GlobalState {
ready: mio::SetReadiness,
tx: Mutex<Sender<Message>>,
tx: mpsc::UnboundedSender<Message>,
ctrl_c: GlobalEventState,
ctrl_break: GlobalEventState,
}
Expand All @@ -55,19 +57,19 @@ struct GlobalEventState {
}

enum Message {
NewEvent(winapi::DWORD, Complete<io::Result<Event>>),
NewEvent(winapi::DWORD, oneshot::Sender<io::Result<Event>>),
}

struct DriverTask {
handle: Handle,
reg: PollEvented<MyRegistration>,
rx: Fuse<Receiver<Message>>,
rx: Fuse<mpsc::UnboundedReceiver<Message>>,
ctrl_c: EventState,
ctrl_break: EventState,
}

struct EventState {
tasks: Vec<(RefCell<Oneshot<()>>, mio::SetReadiness)>,
tasks: Vec<(RefCell<oneshot::Receiver<()>>, mio::SetReadiness)>,
}

impl Event {
Expand All @@ -92,11 +94,11 @@ impl Event {
INIT.call_once(|| {
init = Some(global_init(handle));
});
let new_signal = futures::lazy(move || {
let (tx, rx) = futures::oneshot();
let new_signal = future::lazy(move || {
let (tx, rx) = oneshot::channel();
let msg = Message::NewEvent(signum, tx);
let res = unsafe {
(*GLOBAL_STATE).tx.lock().unwrap().send(msg)
(*GLOBAL_STATE).tx.clone().send(msg)
};
res.expect("failed to request a new signal stream, did the \
first event loop go away?");
Expand Down Expand Up @@ -128,7 +130,7 @@ impl Stream for Event {
}

fn global_init(handle: &Handle) -> io::Result<()> {
let (tx, rx) = try!(channel(handle));
let (tx, rx) = mpsc::unbounded();
let reg = MyRegistration { inner: RefCell::new(None) };
let reg = try!(PollEvented::new(reg, handle));
let ready = reg.get_ref().inner.borrow().as_ref().unwrap().1.clone();
Expand All @@ -137,7 +139,7 @@ fn global_init(handle: &Handle) -> io::Result<()> {
ready: ready,
ctrl_c: GlobalEventState { ready: AtomicBool::new(false) },
ctrl_break: GlobalEventState { ready: AtomicBool::new(false) },
tx: Mutex::new(tx.clone()),
tx: tx,
});
GLOBAL_STATE = Box::into_raw(state);

Expand Down Expand Up @@ -187,11 +189,10 @@ impl DriverTask {
fn check_messages(&mut self) {
loop {
// Acquire the next message
let message = match self.rx.poll() {
Ok(Async::Ready(Some(e))) => e,
Ok(Async::Ready(None)) |
Ok(Async::NotReady) => break,
Err(e) => panic!("error on rx: {}", e),
let message = match self.rx.poll().unwrap() {
Async::Ready(Some(e)) => e,
Async::Ready(None) |
Async::NotReady => break,
};
let (sig, complete) = match message {
Message::NewEvent(sig, complete) => (sig, complete),
Expand All @@ -216,7 +217,7 @@ impl DriverTask {

// Create the `Event` to pass back and then also keep a handle to
// the `SetReadiness` for ourselves internally.
let (tx, rx) = futures::oneshot();
let (tx, rx) = oneshot::channel();
let ready = reg.get_ref().inner.borrow_mut().as_mut().unwrap().1.clone();
complete.complete(Ok(Event {
reg: reg,
Expand Down
32 changes: 0 additions & 32 deletions tests/signal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,41 +5,15 @@ extern crate libc;
extern crate tokio_core;
extern crate tokio_signal;

use std::sync::mpsc::channel;
use std::sync::{Once, ONCE_INIT, Mutex, MutexGuard};
use std::thread;
use std::time::Duration;

use futures::Future;
use futures::stream::Stream;
use tokio_core::reactor::{Core, Timeout};
use tokio_signal::unix::Signal;

static INIT: Once = ONCE_INIT;
static mut LOCK: *mut Mutex<()> = 0 as *mut _;

fn lock() -> MutexGuard<'static, ()> {
unsafe {
INIT.call_once(|| {
LOCK = Box::into_raw(Box::new(Mutex::new(())));
let (tx, rx) = channel();
thread::spawn(move || {
let mut lp = Core::new().unwrap();
let handle = lp.handle();
let _signal = lp.run(Signal::new(libc::SIGALRM, &handle)).unwrap();
tx.send(()).unwrap();
drop(lp.run(futures::empty::<(), ()>()));
});
rx.recv().unwrap();
});
(*LOCK).lock().unwrap()
}
}

#[test]
fn simple() {
let _lock = lock();

let mut lp = Core::new().unwrap();
let handle = lp.handle();
let signal = lp.run(Signal::new(libc::SIGUSR1, &handle)).unwrap();
Expand All @@ -51,8 +25,6 @@ fn simple() {

#[test]
fn notify_both() {
let _lock = lock();

let mut lp = Core::new().unwrap();
let handle = lp.handle();
let signal1 = lp.run(Signal::new(libc::SIGUSR2, &handle)).unwrap();
Expand All @@ -65,8 +37,6 @@ fn notify_both() {

#[test]
fn drop_then_get_a_signal() {
let _lock = lock();

let mut lp = Core::new().unwrap();
let handle = lp.handle();
let signal = lp.run(Signal::new(libc::SIGUSR1, &handle)).unwrap();
Expand All @@ -80,8 +50,6 @@ fn drop_then_get_a_signal() {

#[test]
fn twice() {
let _lock = lock();

let mut lp = Core::new().unwrap();
let handle = lp.handle();
let signal = lp.run(Signal::new(libc::SIGUSR1, &handle)).unwrap();
Expand Down