From ab9841a02fb0c9ebe76e15247e68401fd13474cb Mon Sep 17 00:00:00 2001 From: kyren Date: Wed, 7 Feb 2018 11:16:22 -0500 Subject: [PATCH] Don't keep the unref list around forever after Lua is dropped --- src/lua.rs | 11 ++++++----- src/types.rs | 6 ++++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/lua.rs b/src/lua.rs index 948d142..0b02a14 100644 --- a/src/lua.rs +++ b/src/lua.rs @@ -39,7 +39,7 @@ pub struct Scope<'lua> { // Data associated with the main lua_State via lua_getextraspace. struct ExtraData { registered_userdata: HashMap, - registry_unref_list: Arc>>, + registry_unref_list: Arc>>>, } unsafe impl Send for Lua {} @@ -57,6 +57,7 @@ impl Drop for Lua { } let extra_data = *(ffi::lua_getextraspace(self.state) as *mut *mut ExtraData); + *(*extra_data).registry_unref_list.lock().unwrap() = None; Box::from_raw(extra_data); ffi::lua_close(self.state); @@ -569,10 +570,10 @@ impl Lua { pub fn expire_registry_values(&self) { unsafe { let unref_list = mem::replace( - (*self.extra()).registry_unref_list.lock().unwrap().as_mut(), - Vec::new(), + &mut *(*self.extra()).registry_unref_list.lock().unwrap(), + Some(Vec::new()), ); - for id in unref_list { + for id in unref_list.unwrap() { ffi::luaL_unref(self.state, ffi::LUA_REGISTRYINDEX, id); } } @@ -935,7 +936,7 @@ impl Lua { let extra_data = Box::into_raw(Box::new(ExtraData { registered_userdata: HashMap::new(), - registry_unref_list: Arc::new(Mutex::new(Vec::new())), + registry_unref_list: Arc::new(Mutex::new(Some(Vec::new()))), })); *(ffi::lua_getextraspace(state) as *mut *mut ExtraData) = extra_data; }); diff --git a/src/types.rs b/src/types.rs index de9f4e9..fb3a5d0 100644 --- a/src/types.rs +++ b/src/types.rs @@ -25,14 +25,16 @@ pub struct LightUserData(pub *mut c_void); /// can be used in many situations where it would be impossible to store a regular handle value. pub struct RegistryKey { pub(crate) registry_id: c_int, - pub(crate) unref_list: Arc>>, + pub(crate) unref_list: Arc>>>, pub(crate) drop_unref: bool, } impl Drop for RegistryKey { fn drop(&mut self) { if self.drop_unref { - self.unref_list.lock().unwrap().push(self.registry_id); + if let Some(list) = self.unref_list.lock().unwrap().as_mut() { + list.push(self.registry_id); + } } } }