summaryrefslogtreecommitdiff
path: root/src/types.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/types.rs')
-rw-r--r--src/types.rs37
1 files changed, 33 insertions, 4 deletions
diff --git a/src/types.rs b/src/types.rs
index 7b1f653..9404d10 100644
--- a/src/types.rs
+++ b/src/types.rs
@@ -1,6 +1,7 @@
use std::cell::UnsafeCell;
use std::hash::{Hash, Hasher};
use std::os::raw::{c_int, c_void};
+use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Mutex};
use std::{fmt, mem, ptr};
@@ -104,6 +105,7 @@ pub(crate) struct DestructedUserdata;
/// [`AnyUserData::get_user_value`]: crate::AnyUserData::get_user_value
pub struct RegistryKey {
pub(crate) registry_id: c_int,
+ pub(crate) is_nil: AtomicBool,
pub(crate) unref_list: Arc<Mutex<Option<Vec<c_int>>>>,
}
@@ -129,15 +131,27 @@ impl Eq for RegistryKey {}
impl Drop for RegistryKey {
fn drop(&mut self) {
- let mut unref_list = mlua_expect!(self.unref_list.lock(), "unref list poisoned");
- if let Some(list) = unref_list.as_mut() {
- list.push(self.registry_id);
+ // We don't need to collect nil slot
+ if self.registry_id > ffi::LUA_REFNIL {
+ let mut unref_list = mlua_expect!(self.unref_list.lock(), "unref list poisoned");
+ if let Some(list) = unref_list.as_mut() {
+ list.push(self.registry_id);
+ }
}
}
}
impl RegistryKey {
- // Destroys the RegistryKey without adding to the drop list
+ // Creates a new instance of `RegistryKey`
+ pub(crate) const fn new(id: c_int, unref_list: Arc<Mutex<Option<Vec<c_int>>>>) -> Self {
+ RegistryKey {
+ registry_id: id,
+ is_nil: AtomicBool::new(id == ffi::LUA_REFNIL),
+ unref_list,
+ }
+ }
+
+ // Destroys the `RegistryKey` without adding to the unref list
pub(crate) fn take(self) -> c_int {
let registry_id = self.registry_id;
unsafe {
@@ -146,6 +160,21 @@ impl RegistryKey {
}
registry_id
}
+
+ // Returns true if this `RegistryKey` holds a nil value
+ #[inline(always)]
+ pub(crate) fn is_nil(&self) -> bool {
+ self.is_nil.load(Ordering::Relaxed)
+ }
+
+ // Marks value of this `RegistryKey` as `Nil`
+ #[inline(always)]
+ pub(crate) fn set_nil(&self, enabled: bool) {
+ // We cannot replace previous value with nil in as this will break
+ // Lua mechanism to find free keys.
+ // Instead, we set a special flag to mark value as nil.
+ self.is_nil.store(enabled, Ordering::Relaxed);
+ }
}
pub(crate) struct LuaRef<'lua> {