Skip to content

Commit 1f32754

Browse files
committed
Relax UserDataBorrowRef restrictions to allow recursive calls
1 parent c2eab17 commit 1f32754

File tree

2 files changed

+8
-13
lines changed

2 files changed

+8
-13
lines changed

src/userdata/cell.rs

+6-10
Original file line numberDiff line numberDiff line change
@@ -291,11 +291,7 @@ pub(crate) struct UserDataBorrowRef<'a, T>(&'a UserDataVariant<T>);
291291
impl<T> Drop for UserDataBorrowRef<'_, T> {
292292
#[inline]
293293
fn drop(&mut self) {
294-
if !cfg!(feature = "send") || is_sync::<T>() {
295-
unsafe { self.0.raw_lock().unlock_shared() };
296-
} else {
297-
unsafe { self.0.raw_lock().unlock_exclusive() };
298-
}
294+
unsafe { self.0.raw_lock().unlock_shared() };
299295
}
300296
}
301297

@@ -314,11 +310,11 @@ impl<'a, T> TryFrom<&'a UserDataVariant<T>> for UserDataBorrowRef<'a, T> {
314310

315311
#[inline(always)]
316312
fn try_from(variant: &'a UserDataVariant<T>) -> Result<Self> {
317-
if !cfg!(feature = "send") || is_sync::<T>() {
318-
if !variant.raw_lock().try_lock_shared() {
319-
return Err(Error::UserDataBorrowError);
320-
}
321-
} else if !variant.raw_lock().try_lock_exclusive() {
313+
// We don't need to check for `T: Sync` because when this method is used (internally),
314+
// Lua mutex is already locked.
315+
// If non-`Sync` userdata is already borrowed by another thread (via `UserDataRef`), it will be
316+
// exclusively locked.
317+
if !variant.raw_lock().try_lock_shared() {
322318
return Err(Error::UserDataBorrowError);
323319
}
324320
Ok(UserDataBorrowRef(variant))

tests/send.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,11 @@ fn test_userdata_multithread_access_send_only() -> Result<()> {
2020
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
2121
methods.add_method("method", |lua, this, ()| {
2222
let ud = lua.globals().get::<AnyUserData>("ud")?;
23-
assert!((ud.call_method::<()>("method2", ()).err().unwrap().to_string())
24-
.contains("error borrowing userdata"));
23+
assert_eq!(ud.call_method::<String>("method2", ())?, "method2");
2524
Ok(this.0.clone())
2625
});
2726

28-
methods.add_method("method2", |_, _, ()| Ok(()));
27+
methods.add_method("method2", |_, _, ()| Ok("method2"));
2928
}
3029
}
3130

0 commit comments

Comments
 (0)