@@ -1105,21 +1105,45 @@ mod _sqlite3 {
11051105 ..
11061106 } = args;
11071107
1108- zelf. statement_cache . lock ( ) . capacity = cached_statements. max ( 0 ) as usize ;
1109-
1110- zelf. detect_types . store ( detect_types, Ordering :: Relaxed ) ;
1111- zelf. check_same_thread
1112- . store ( check_same_thread, Ordering :: Relaxed ) ;
1113- * zelf. autocommit . lock ( ) = autocommit;
1114- * zelf. thread_ident . lock ( ) = std:: thread:: current ( ) . id ( ) ;
1115- let _ = unsafe { zelf. isolation_level . swap ( isolation_level. 0 ) } ;
1116-
1117- let previous = zelf. db . lock ( ) . replace ( db) ;
1118- Radium :: store ( & zelf. initialized , true , Ordering :: Release ) ;
1119- // An old callback's finalizer can reenter __init__ during teardown.
1120- // Release any database it installed without holding the Rust lock.
1121- with_deferred_drops ( || drop ( previous) ) ;
1122- Ok ( ( ) )
1108+ loop {
1109+ let mut current = zelf. db . lock ( ) ;
1110+ if current. is_none ( ) {
1111+ let previous = unsafe { zelf. isolation_level . swap ( isolation_level. 0 . clone ( ) ) } ;
1112+ if previous. as_ref ( ) . is_some_and ( |previous| {
1113+ !isolation_level
1114+ . 0
1115+ . as_ref ( )
1116+ . is_some_and ( |requested| previous. is ( requested) )
1117+ } ) {
1118+ // A str subclass can finalize too. Keep the requested
1119+ // value alive, but retire other values before publication.
1120+ drop ( current) ;
1121+ with_deferred_drops ( || drop ( previous) ) ;
1122+ continue ;
1123+ }
1124+
1125+ // No destructor-capable owner remains to release here.
1126+ // Publish the settings and database under the same lock.
1127+ zelf. statement_cache . lock ( ) . capacity = cached_statements. max ( 0 ) as usize ;
1128+ zelf. detect_types . store ( detect_types, Ordering :: Relaxed ) ;
1129+ zelf. check_same_thread
1130+ . store ( check_same_thread, Ordering :: Relaxed ) ;
1131+ * zelf. autocommit . lock ( ) = autocommit;
1132+ * zelf. thread_ident . lock ( ) = std:: thread:: current ( ) . id ( ) ;
1133+ * current = Some ( db) ;
1134+ Radium :: store ( & zelf. initialized , true , Ordering :: Release ) ;
1135+ return Ok ( ( ) ) ;
1136+ }
1137+ drop ( current) ;
1138+
1139+ // A concurrent initializer or finalizer installed another database.
1140+ // Finish its teardown outside the lock before trying to publish.
1141+ with_deferred_drops ( || {
1142+ Radium :: store ( & zelf. initialized , false , Ordering :: Release ) ;
1143+ zelf. reset_factories ( vm) ;
1144+ zelf. drop_db ( vm)
1145+ } ) ?;
1146+ }
11231147 }
11241148 }
11251149
0 commit comments