diff --git a/src/lune/scheduler/impl_async.rs b/src/lune/scheduler/impl_async.rs
index f57ec3b..6f9a83e 100644
--- a/src/lune/scheduler/impl_async.rs
+++ b/src/lune/scheduler/impl_async.rs
@@ -39,12 +39,8 @@ where
self.schedule_future(async move {
match fut.await.and_then(|rets| rets.into_lua_multi(self.lua)) {
Err(e) => {
- self.state.set_lua_error(e);
- // NOTE: We push the thread to the front of the scheduler
- // to ensure that it runs first to be able to catch the
- // stored error from within the scheduler lua interrupt
- self.push_front(thread, ())
- .expect("Failed to schedule future thread");
+ self.push_err(thread, e)
+ .expect("Failed to schedule future err thread");
}
Ok(v) => {
self.push_back(thread, v)
diff --git a/src/lune/scheduler/impl_runner.rs b/src/lune/scheduler/impl_runner.rs
index 088bf23..82617cf 100644
--- a/src/lune/scheduler/impl_runner.rs
+++ b/src/lune/scheduler/impl_runner.rs
@@ -23,29 +23,45 @@ where
let mut resumed_any = false;
- while let Some((thread, args, sender)) = self
+ // Pop threads from the scheduler until there are none left
+ while let Some(thread) = self
.pop_thread()
.expect("Failed to pop thread from scheduler")
{
+ // Deconstruct the scheduler thread into its parts
+ let thread_id = thread.id();
+ let (thread, args) = thread.into_inner(self.lua);
+
+ // Resume the thread, ensuring that the schedulers
+ // current thread id is set correctly for error catching
+ self.state.set_current_thread_id(Some(thread_id));
let res = thread.resume::<_, LuaMultiValue>(args);
- self.state.add_resumption();
+ self.state.set_current_thread_id(None);
+
resumed_any = true;
+ // If we got any resumption (lua-side) error, increment
+ // the error count of the scheduler so we can exit with
+ // a non-zero exit code, and print it out to stderr
+ // TODO: Pretty print the lua error here
if let Err(err) = &res {
- self.state.add_error();
- eprint!("{err}"); // TODO: Pretty print the lua error here
+ self.state.increment_error_count();
+ eprint!("{err}");
}
- if sender.receiver_count() > 0 {
- sender
- .send(res.map(|v| {
- Arc::new(
- self.lua
- .create_registry_value(v.into_vec())
- .expect("Failed to store return values in registry"),
- )
- }))
- .expect("Failed to broadcast return values of thread");
+ // Send results of resuming this thread to any listeners
+ if let Some(sender) = self.thread_senders.borrow_mut().remove(&thread_id) {
+ if sender.receiver_count() > 0 {
+ sender
+ .send(res.map(|v| {
+ Arc::new(
+ self.lua
+ .create_registry_value(v.into_vec())
+ .expect("Failed to store return values in registry"),
+ )
+ }))
+ .expect("Failed to broadcast return values of thread");
+ }
}
if self.state.has_exit_code() {
diff --git a/src/lune/scheduler/impl_threads.rs b/src/lune/scheduler/impl_threads.rs
index 2f8969f..765bbb7 100644
--- a/src/lune/scheduler/impl_threads.rs
+++ b/src/lune/scheduler/impl_threads.rs
@@ -27,9 +27,7 @@ where
Returns `None` if there are no threads left to run.
*/
- pub(super) fn pop_thread(
- &self,
- ) -> LuaResult