Skip to content

Instantly share code, notes, and snippets.

@alexcrichton
Created December 17, 2016 20:52
Show Gist options
  • Save alexcrichton/6b35e23e44e07b94ee2803d5e330f325 to your computer and use it in GitHub Desktop.
Save alexcrichton/6b35e23e44e07b94ee2803d5e330f325 to your computer and use it in GitHub Desktop.
// 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