11use std:: any:: { type_name, TypeId } ;
2- use std:: cell:: { RefCell , UnsafeCell } ;
2+ use std:: cell:: { Cell , RefCell , UnsafeCell } ;
33use std:: fmt;
44use std:: ops:: { Deref , DerefMut } ;
55use std:: os:: raw:: c_int;
@@ -99,6 +99,15 @@ impl<T> UserDataVariant<T> {
9999 }
100100 }
101101
102+ #[ inline( always) ]
103+ fn borrow_count ( & self ) -> & Cell < usize > {
104+ match self {
105+ Self :: Default ( inner) => & inner. borrow_count ,
106+ #[ cfg( feature = "serialize" ) ]
107+ Self :: Serializable ( inner) => & inner. borrow_count ,
108+ }
109+ }
110+
102111 #[ inline( always) ]
103112 fn as_ptr ( & self ) -> * mut T {
104113 match self {
@@ -130,6 +139,7 @@ impl Serialize for UserDataStorage<()> {
130139/// A type that provides interior mutability for a userdata value (thread-safe).
131140pub ( crate ) struct UserDataCell < T > {
132141 raw_lock : RawLock ,
142+ borrow_count : Cell < usize > ,
133143 value : UnsafeCell < T > ,
134144}
135145
@@ -143,6 +153,7 @@ impl<T> UserDataCell<T> {
143153 fn new ( value : T ) -> Self {
144154 UserDataCell {
145155 raw_lock : RawLock :: INIT ,
156+ borrow_count : Cell :: new ( 0 ) ,
146157 value : UnsafeCell :: new ( value) ,
147158 }
148159 }
@@ -291,7 +302,10 @@ pub(crate) struct UserDataBorrowRef<'a, T>(&'a UserDataVariant<T>);
291302impl < T > Drop for UserDataBorrowRef < ' _ , T > {
292303 #[ inline]
293304 fn drop ( & mut self ) {
294- unsafe { self . 0 . raw_lock ( ) . unlock_shared ( ) } ;
305+ unsafe {
306+ self . 0 . borrow_count ( ) . set ( self . 0 . borrow_count ( ) . get ( ) - 1 ) ;
307+ self . 0 . raw_lock ( ) . unlock_shared ( ) ;
308+ }
295309 }
296310}
297311
@@ -317,6 +331,7 @@ impl<'a, T> TryFrom<&'a UserDataVariant<T>> for UserDataBorrowRef<'a, T> {
317331 if !variant. raw_lock ( ) . try_lock_shared ( ) {
318332 return Err ( Error :: UserDataBorrowError ) ;
319333 }
334+ variant. borrow_count ( ) . set ( variant. borrow_count ( ) . get ( ) + 1 ) ;
320335 Ok ( UserDataBorrowRef ( variant) )
321336 }
322337}
@@ -326,7 +341,10 @@ pub(crate) struct UserDataBorrowMut<'a, T>(&'a UserDataVariant<T>);
326341impl < T > Drop for UserDataBorrowMut < ' _ , T > {
327342 #[ inline]
328343 fn drop ( & mut self ) {
329- unsafe { self . 0 . raw_lock ( ) . unlock_exclusive ( ) } ;
344+ unsafe {
345+ self . 0 . borrow_count ( ) . set ( self . 0 . borrow_count ( ) . get ( ) - 1 ) ;
346+ self . 0 . raw_lock ( ) . unlock_exclusive ( ) ;
347+ }
330348 }
331349}
332350
@@ -354,6 +372,7 @@ impl<'a, T> TryFrom<&'a UserDataVariant<T>> for UserDataBorrowMut<'a, T> {
354372 if !variant. raw_lock ( ) . try_lock_exclusive ( ) {
355373 return Err ( Error :: UserDataBorrowMutError ) ;
356374 }
375+ variant. borrow_count ( ) . set ( variant. borrow_count ( ) . get ( ) + 1 ) ;
357376 Ok ( UserDataBorrowMut ( variant) )
358377 }
359378}
@@ -470,6 +489,14 @@ impl<T> UserDataStorage<T> {
470489 Self :: Scoped ( ScopedUserDataVariant :: Boxed ( RefCell :: new ( data) ) )
471490 }
472491
492+ #[ inline( always) ]
493+ pub ( crate ) fn is_borrowed ( & self ) -> bool {
494+ match self {
495+ Self :: Owned ( variant) => variant. borrow_count ( ) . get ( ) > 0 ,
496+ Self :: Scoped ( _) => true ,
497+ }
498+ }
499+
473500 #[ inline]
474501 pub ( crate ) fn try_borrow_scoped < R > ( & self , f : impl FnOnce ( & T ) -> R ) -> Result < R > {
475502 match self {
0 commit comments