Skip to content

Commit 14ef873

Browse files
authored
Merge pull request #253 from Berrysoft/fix/spawn-blocking-busy
2 parents 49e4be9 + d94f2ce commit 14ef873

File tree

1 file changed

+26
-3
lines changed
  • compio-runtime/src/runtime

1 file changed

+26
-3
lines changed

compio-runtime/src/runtime/mod.rs

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::{
22
any::Any,
33
cell::RefCell,
44
collections::VecDeque,
5-
future::{ready, Future},
5+
future::{poll_fn, ready, Future},
66
io,
77
panic::AssertUnwindSafe,
88
rc::{Rc, Weak},
@@ -134,8 +134,31 @@ impl RuntimeInner {
134134
let res = std::panic::catch_unwind(AssertUnwindSafe(f));
135135
BufResult(Ok(0), res)
136136
});
137-
// SAFETY: Just like spawn.
138-
unsafe { self.spawn_unchecked(self.submit(op).map(|BufResult(_, op)| op.into_inner())) }
137+
let closure = async move {
138+
let mut op = op;
139+
loop {
140+
match self.submit(op).await {
141+
BufResult(Ok(_), rop) => break rop.into_inner(),
142+
BufResult(Err(_), rop) => op = rop,
143+
}
144+
// Possible error: thread pool is full, or failed to create notify handle.
145+
// Push the future to the back of the queue.
146+
let mut yielded = false;
147+
poll_fn(|cx| {
148+
if yielded {
149+
Poll::Ready(())
150+
} else {
151+
yielded = true;
152+
cx.waker().wake_by_ref();
153+
Poll::Pending
154+
}
155+
})
156+
.await;
157+
}
158+
};
159+
// SAFETY: the closure catches the shared reference of self, which is in an Rc
160+
// so it won't be moved.
161+
unsafe { self.spawn_unchecked(closure) }
139162
}
140163

141164
pub fn attach(&self, fd: RawFd) -> io::Result<()> {

0 commit comments

Comments
 (0)