Created
December 17, 2016 20:52
-
-
Save alexcrichton/6b35e23e44e07b94ee2803d5e330f325 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// crash.rs | |
extern crate futures; | |
use futures::{Async, Future, Poll}; | |
use futures::sync::oneshot; | |
enum State<W> { | |
Writing(W, oneshot::Sender<()>), | |
BetweenWrites(W), | |
Empty, | |
} | |
pub struct WriteQueue<W> { | |
pending: Option<oneshot::Sender<()>>, | |
state: State<W>, | |
} | |
impl <W> WriteQueue<W> { | |
pub fn new(writer: W) -> WriteQueue<W> | |
{ | |
let (complete, _) = futures::oneshot(); | |
WriteQueue { | |
pending: Some(complete), | |
state: State::BetweenWrites(writer), | |
} | |
} | |
} | |
enum IntermediateState<W> { | |
WriteDone(W), | |
StartWrite(oneshot::Sender<()>), | |
Resolve, | |
} | |
impl <W> Future for WriteQueue<W> { | |
type Item = (); | |
type Error = (); | |
#[inline(never)] | |
fn poll(&mut self) -> Poll<Self::Item, Self::Error> { | |
#[inline(never)] | |
#[no_mangle] | |
fn diverge() -> ! { panic!() } | |
loop { | |
let next: IntermediateState<W> = match self.state { | |
State::Writing(..) => { | |
return Err(()) | |
} | |
State::BetweenWrites(ref mut _writer) => { | |
let front = self.pending.take(); | |
match front { | |
Some(complete) => { | |
IntermediateState::StartWrite(complete) | |
} | |
None => diverge(), | |
} | |
} | |
State::Empty => diverge(), | |
}; | |
match next { | |
IntermediateState::WriteDone(_w) => diverge(), | |
IntermediateState::StartWrite(c) => { | |
let new_state = match ::std::mem::replace(&mut self.state, State::Empty) { | |
State::BetweenWrites(w) => { | |
State::Writing(w, c) | |
} | |
_ => diverge(), | |
}; | |
unsafe { | |
std::ptr::write(&mut self.state, new_state); | |
} | |
} | |
IntermediateState::Resolve => { | |
match ::std::mem::replace(&mut self.state, State::Empty) { | |
State::BetweenWrites(_w) => { | |
return Ok(Async::Ready(())) | |
} | |
_ => diverge(), | |
} | |
} | |
} | |
} | |
} | |
} | |
fn main() { | |
let (a, b) = futures::sync::BiLock::new(()); | |
std::mem::forget(a); | |
WriteQueue::new(b).poll(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment