diff --git a/lib/queue.rs b/lib/queue.rs index 172ed67..eb10928 100644 --- a/lib/queue.rs +++ b/lib/queue.rs @@ -46,6 +46,7 @@ impl ThreadQueue { Ok(id) } + #[inline] pub fn drain_items<'outer, 'lua>( &'outer self, lua: &'lua Lua, @@ -56,11 +57,17 @@ impl ThreadQueue { self.queue.try_iter().map(|stored| stored.into_inner(lua)) } + #[inline] pub async fn wait_for_item(&self) { if self.queue.is_empty() { self.event.listen().await; } } + + #[inline] + pub fn is_empty(&self) -> bool { + self.queue.is_empty() + } } /** diff --git a/lib/runtime.rs b/lib/runtime.rs index 618f0cb..6759679 100644 --- a/lib/runtime.rs +++ b/lib/runtime.rs @@ -5,6 +5,7 @@ use std::{ process::ExitCode, rc::{Rc, Weak as WeakRc}, sync::{Arc, Weak as WeakArc}, + thread::panicking, }; use futures_lite::prelude::*; @@ -417,7 +418,10 @@ impl<'lua> Runtime<'lua> { // Empty executor = we didn't spawn any new Lua tasks // above, and there are no remaining tasks to run later - if local_exec.is_empty() { + if local_exec.is_empty() + && self.queue_spawn.is_empty() + && self.queue_defer.is_empty() + { break; } } @@ -445,20 +449,31 @@ impl<'lua> Runtime<'lua> { impl Drop for Runtime<'_> { fn drop(&mut self) { - self.lua - .remove_app_data::() - .expect(ERR_METADATA_REMOVED); - self.lua - .remove_app_data::() - .expect(ERR_METADATA_REMOVED); - self.lua - .remove_app_data::() - .expect(ERR_METADATA_REMOVED); - self.lua - .remove_app_data::() - .expect(ERR_METADATA_REMOVED); - self.lua - .remove_app_data::() - .expect(ERR_METADATA_REMOVED); + if panicking() { + // Do not cause further panics if already panicking, as + // this may abort the program instead of safely unwinding + self.lua.remove_app_data::(); + self.lua.remove_app_data::(); + self.lua.remove_app_data::(); + self.lua.remove_app_data::(); + self.lua.remove_app_data::(); + } else { + // In any other case we panic if metadata was removed incorrectly + self.lua + .remove_app_data::() + .expect(ERR_METADATA_REMOVED); + self.lua + .remove_app_data::() + .expect(ERR_METADATA_REMOVED); + self.lua + .remove_app_data::() + .expect(ERR_METADATA_REMOVED); + self.lua + .remove_app_data::() + .expect(ERR_METADATA_REMOVED); + self.lua + .remove_app_data::() + .expect(ERR_METADATA_REMOVED); + } } }