@@ -70,7 +70,10 @@ impl Attached {
7070 fn drop ( & mut self ) {
7171 // Reset database to null if we did anything in `DbGuard::new`.
7272 if let Some ( attached) = self . state {
73- attached. database . set ( None ) ;
73+ if let Some ( prev) = attached. database . replace ( None ) {
74+ // SAFETY: `prev` is a valid pointer to a database.
75+ unsafe { prev. as_ref ( ) . zalsa_local ( ) . uncancel ( ) } ;
76+ }
7477 }
7578 }
7679 }
@@ -85,25 +88,50 @@ impl Attached {
8588 Db : ?Sized + Database ,
8689 {
8790 struct DbGuard < ' s > {
88- state : & ' s Attached ,
91+ state : Option < & ' s Attached > ,
8992 prev : Option < NonNull < dyn Database > > ,
9093 }
9194
9295 impl < ' s > DbGuard < ' s > {
9396 #[ inline]
9497 fn new ( attached : & ' s Attached , db : & dyn Database ) -> Self {
95- let prev = attached. database . replace ( Some ( NonNull :: from ( db) ) ) ;
96- Self {
97- state : attached,
98- prev,
98+ let db = NonNull :: from ( db) ;
99+ match attached. database . replace ( Some ( db) ) {
100+ Some ( prev) => {
101+ if std:: ptr:: eq ( db. as_ptr ( ) , prev. as_ptr ( ) ) {
102+ Self {
103+ state : None ,
104+ prev : None ,
105+ }
106+ } else {
107+ Self {
108+ state : Some ( attached) ,
109+ prev : Some ( prev) ,
110+ }
111+ }
112+ }
113+ None => {
114+ // Otherwise, set the database.
115+ attached. database . set ( Some ( db) ) ;
116+ Self {
117+ state : Some ( attached) ,
118+ prev : None ,
119+ }
120+ }
99121 }
100122 }
101123 }
102124
103125 impl Drop for DbGuard < ' _ > {
104126 #[ inline]
105127 fn drop ( & mut self ) {
106- self . state . database . set ( self . prev ) ;
128+ // Reset database to null if we did anything in `DbGuard::new`.
129+ if let Some ( attached) = self . state {
130+ if let Some ( prev) = attached. database . replace ( self . prev ) {
131+ // SAFETY: `prev` is a valid pointer to a database.
132+ unsafe { prev. as_ref ( ) . zalsa_local ( ) . uncancel ( ) } ;
133+ }
134+ }
107135 }
108136 }
109137
0 commit comments