Skip to content

Instantly share code, notes, and snippets.

@nmccarty
Last active May 16, 2020 22:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nmccarty/0df7130b40a62c380e8d0a3c46f48e86 to your computer and use it in GitHub Desktop.
Save nmccarty/0df7130b40a62c380e8d0a3c46f48e86 to your computer and use it in GitHub Desktop.
Smol 0.1.5 deadlock on windows
[package]
name = "smol-bug"
version = "0.1.0"
authors = ["Nathan McCarty <nathan@mccarty.io>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
smol = "=0.1.5"
futures = { version = "0.3.5", default-features = false, features = ["std"] }
use futures::channel::mpsc;
use futures::channel::oneshot;
use futures::sink::SinkExt;
use futures::stream::StreamExt;
use smol::block_on;
use std::thread;
#[derive(Debug)]
struct StoredArchive {}
#[derive(Debug)]
struct InternalManifest {}
impl InternalManifest {
fn open() -> InternalManifest {
InternalManifest {}
}
fn archive_iterator(&self) -> std::vec::IntoIter<StoredArchive> {
Vec::new().into_iter()
}
}
enum ManifestCommand {
ArchiveIterator(oneshot::Sender<std::vec::IntoIter<StoredArchive>>),
Close(oneshot::Sender<()>),
}
#[derive(Clone)]
pub struct Manifest {
input: mpsc::Sender<ManifestCommand>,
}
impl Manifest {
pub fn open() -> Manifest {
let queue_depth = 4;
let manifest = InternalManifest::open();
let (input, mut output) = mpsc::channel(queue_depth);
thread::spawn(move || {
let mut final_ret = None;
while let Some(command) = block_on(output.next()) {
match command {
ManifestCommand::ArchiveIterator(ret) => {
ret.send(manifest.archive_iterator()).expect("what");
}
ManifestCommand::Close(ret) => {
final_ret = Some(ret);
break;
}
}
}
std::mem::drop(manifest);
std::mem::drop(output);
if let Some(ret) = final_ret {
ret.send(()).unwrap();
};
});
Manifest { input }
}
pub async fn close(&mut self) {
let (i, o) = oneshot::channel();
self.input.send(ManifestCommand::Close(i)).await.unwrap();
o.await.unwrap();
}
async fn archive_iterator(&mut self) -> std::vec::IntoIter<StoredArchive> {
let (i, o) = oneshot::channel();
self.input
.send(ManifestCommand::ArchiveIterator(i))
.await
.unwrap();
o.await.unwrap()
}
}
fn main() {
smol::run(async {
// Create the manifest
let mut manifest = Manifest::open();
manifest.close().await;
// Reopen the manifest
let mut manifest = Manifest::open();
// Pull the archives out of it
// This is the part that seems to trigger the bug
let _archives: Vec<StoredArchive> = manifest.archive_iterator().await.collect();
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment