Skip to content

Commit 1b21275

Browse files
committed
Add code examples
1 parent d8f6db8 commit 1b21275

File tree

4 files changed

+79
-0
lines changed

4 files changed

+79
-0
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
workspace = { members = ["members/spawn-blocking-lib"] }
2+
[package]
3+
name = "spawn-blocking-workspace"
4+
version = "0.1.0"
5+
edition = "2021"
6+
7+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8+
9+
[dependencies]
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[package]
2+
name = "spawn-blocking-lib"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[dependencies]
9+
10+
async-std = "1.7"
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
use std::sync::{Arc, Mutex};
2+
use std::task::Waker;
3+
4+
pub struct SpawnBlocking<T>(Arc<Mutex<Shared<T>>>);
5+
6+
struct Shared<T> {
7+
value: Option<T>,
8+
waker: Option<Waker>,
9+
}
10+
11+
pub fn spawn_blocking<T, F>(closure: F) -> SpawnBlocking<T>
12+
where F: FnOnce() -> T,
13+
F: Send + 'static,
14+
T: Send + 'static,
15+
{
16+
let inner = Arc::new(Mutex::new(Shared {
17+
value: None,
18+
waker: None,
19+
}));
20+
21+
std::thread::spawn({
22+
let inner = inner.clone();
23+
move || {
24+
let value = closure();
25+
26+
let maybe_waker = {
27+
let mut guard = inner.lock().unwrap();
28+
guard.value = Some(value);
29+
guard.waker.take()
30+
};
31+
32+
if let Some(waker) = maybe_waker {
33+
waker.wake();
34+
}
35+
}
36+
});
37+
38+
SpawnBlocking(inner)
39+
}
40+
41+
use std::future::Future;
42+
use std::pin::Pin;
43+
use std::task::{Context, Poll};
44+
45+
impl<T: Send> Future for SpawnBlocking<T> {
46+
type Output = T;
47+
48+
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<T> {
49+
let mut guard = self.0.lock().unwrap();
50+
if let Some(value) = guard.value.take() {
51+
return Poll::Ready(value);
52+
}
53+
54+
guard.waker = Some(cx.waker().clone());
55+
Poll::Pending
56+
}
57+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fn main() {
2+
println!("Hello, world!");
3+
}

0 commit comments

Comments
 (0)