DataDog / glommio

Glommio is a thread-per-core crate that makes writing highly parallel asynchronous applications in a thread-per-core architecture easier for rustaceans.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

futures::try_join on DmaStreamWriter can cause panic

tontinton opened this issue · comments

Calling poll_write after it returned Pending results in crash. This in itself might be ok, but futures::try_join! triggers this behavior, so we should either fix the bug or at least document that.

This program triggers the crash:

use futures::{try_join, AsyncWriteExt};
use glommio::{
    io::{DmaFile, DmaStreamWriterBuilder},
    LocalExecutorBuilder, Placement,
};

fn main() {
    let builder = LocalExecutorBuilder::new(Placement::Fixed(1));
    builder
        .spawn(|| async move {
            let file1 = DmaFile::create("/tmp/bug1").await.unwrap();
            let mut writer1 = DmaStreamWriterBuilder::new(file1)
                .with_write_behind(1)
                .with_buffer_size(4096)
                .build();
            let file2 = DmaFile::create("/tmp/bug2").await.unwrap();
            let mut writer2 = DmaStreamWriterBuilder::new(file2)
                .with_write_behind(1)
                .with_buffer_size(4096)
                .build();
            let buf = [b'A'; 4096];
            println!("Writing...");
            for _ in 0..100000 {
                try_join!(writer1.write_all(&buf), writer2.write_all(&buf)).unwrap();  // Crash here
            }

        })
        .unwrap()
        .join()
        .unwrap();

    println!("No bug!");
}

With the following output:

Writing...
thread 'unnamed-1' panicked at /home/tony/.cargo/registry/src/index.crates.io-6f17d22bba15001f/glommio-0.8.0/src/io/dma_file_stream.rs:832:9:
assertion failed: self.waker.is_none()
stack backtrace:
   0: rust_begin_unwind
             at /rustc/cc66ad468955717ab92600c770da8c1601a4ff33/library/std/src/panicking.rs:595:5
   1: core::panicking::panic_fmt
             at /rustc/cc66ad468955717ab92600c770da8c1601a4ff33/library/core/src/panicking.rs:67:14
   2: core::panicking::panic
             at /rustc/cc66ad468955717ab92600c770da8c1601a4ff33/library/core/src/panicking.rs:117:5
   3: glommio::io::dma_file_stream::DmaStreamWriterState::add_waker
             at /home/tony/.cargo/registry/src/index.crates.io-6f17d22bba15001f/glommio-0.8.0/src/io/dma_file_stream.rs:832:9
   4: <&glommio::io::dma_file_stream::DmaStreamWriter as futures_io::if_std::AsyncWrite>::poll_write
             at /home/tony/.cargo/registry/src/index.crates.io-6f17d22bba15001f/glommio-0.8.0/src/io/dma_file_stream.rs:1369:13
   5: <glommio::io::dma_file_stream::DmaStreamWriter as futures_io::if_std::AsyncWrite>::poll_write
             at /home/tony/.cargo/registry/src/index.crates.io-6f17d22bba15001f/glommio-0.8.0/src/io/dma_file_stream.rs:1310:9
   6: <&mut T as futures_io::if_std::AsyncWrite>::poll_write
             at /home/tony/.cargo/registry/src/index.crates.io-6f17d22bba15001f/futures-io-0.3.28/src/lib.rs:381:17
   7: <futures_util::io::write_all::WriteAll<W> as core::future::future::Future>::poll
             at /home/tony/.cargo/registry/src/index.crates.io-6f17d22bba15001f/futures-util-0.3.28/src/io/write_all.rs:31:28
   8: <futures_util::future::maybe_done::MaybeDone<Fut> as core::future::future::Future>::poll
             at /home/tony/.cargo/registry/src/index.crates.io-6f17d22bba15001f/futures-util-0.3.28/src/future/maybe_done.rs:95:38
   9: glommio_bug::main::{{closure}}::{{closure}}::{{closure}}
             at /home/tony/.cargo/registry/src/index.crates.io-6f17d22bba15001f/futures-util-0.3.28/src/async_await/join_mod.rs:105:13
  10: <futures_util::future::poll_fn::PollFn<F> as core::future::future::Future>::poll
             at /home/tony/.cargo/registry/src/index.crates.io-6f17d22bba15001f/futures-util-0.3.28/src/future/poll_fn.rs:56:9
  11: glommio_bug::main::{{closure}}::{{closure}}
             at ./src/main.rs:24:17
  12: glommio::executor::LocalExecutorBuilder::spawn::{{closure}}::{{closure}}
             at /home/tony/.cargo/registry/src/index.crates.io-6f17d22bba15001f/glommio-0.8.0/src/executor/mod.rs:717:50
  13: glommio::executor::LocalExecutor::run::{{closure}}::{{closure}}
             at /home/tony/.cargo/registry/src/index.crates.io-6f17d22bba15001f/glommio-0.8.0/src/executor/mod.rs:1462:49
  14: <core::pin::Pin<P> as core::future::future::Future>::poll
             at /rustc/cc66ad468955717ab92600c770da8c1601a4ff33/library/core/src/future/future.rs:125:9
  15: glommio::task::raw::RawTask<F,R,S>::run
             at /home/tony/.cargo/registry/src/index.crates.io-6f17d22bba15001f/glommio-0.8.0/src/task/raw.rs:470:20
  16: glommio::task::task_impl::Task::run
             at /home/tony/.cargo/registry/src/index.crates.io-6f17d22bba15001f/glommio-0.8.0/src/task/task_impl.rs:125:22
  17: glommio::executor::LocalExecutor::run_one_task_queue
             at /home/tony/.cargo/registry/src/index.crates.io-6f17d22bba15001f/glommio-0.8.0/src/executor/mod.rs:1382:29
  18: glommio::executor::LocalExecutor::run_task_queues
             at /home/tony/.cargo/registry/src/index.crates.io-6f17d22bba15001f/glommio-0.8.0/src/executor/mod.rs:1333:17
  19: glommio::executor::LocalExecutor::run::{{closure}}
             at /home/tony/.cargo/registry/src/index.crates.io-6f17d22bba15001f/glommio-0.8.0/src/executor/mod.rs:1487:27
  20: glommio::executor::LocalExecutor::run::{{closure}}
             at /home/tony/.cargo/registry/src/index.crates.io-6f17d22bba15001f/glommio-0.8.0/src/executor/mod.rs:1522:35
  21: scoped_tls::ScopedKey<T>::set
             at /home/tony/.cargo/registry/src/index.crates.io-6f17d22bba15001f/scoped-tls-1.0.1/src/lib.rs:137:9
  22: glommio::executor::LocalExecutor::run
             at /home/tony/.cargo/registry/src/index.crates.io-6f17d22bba15001f/glommio-0.8.0/src/executor/mod.rs:1522:13
  23: glommio::executor::LocalExecutorBuilder::spawn::{{closure}}
             at /home/tony/.cargo/registry/src/index.crates.io-6f17d22bba15001f/glommio-0.8.0/src/executor/mod.rs:717:17
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
thread 'main' panicked at src/main.rs:31:10:
called `Result::unwrap()` on an `Err` value: Thread panicked { .. }
stack backtrace:
   0: rust_begin_unwind
             at /rustc/cc66ad468955717ab92600c770da8c1601a4ff33/library/std/src/panicking.rs:595:5
   1: core::panicking::panic_fmt
             at /rustc/cc66ad468955717ab92600c770da8c1601a4ff33/library/core/src/panicking.rs:67:14
   2: core::result::unwrap_failed
             at /rustc/cc66ad468955717ab92600c770da8c1601a4ff33/library/core/src/result.rs:1652:5
   3: core::result::Result<T,E>::unwrap
             at /rustc/cc66ad468955717ab92600c770da8c1601a4ff33/library/core/src/result.rs:1077:23
   4: glommio_bug::main
             at ./src/main.rs:9:5
   5: core::ops::function::FnOnce::call_once
             at /rustc/cc66ad468955717ab92600c770da8c1601a4ff33/library/core/src/ops/function.rs:250:5

One fix I could think of is that when self.waker is not none, simply return Pending again.

I can upload a PR if you are fine with this solution.

Got excited and opened a PR :) #611