File tree Expand file tree Collapse file tree 2 files changed +8
-8
lines changed
Expand file tree Collapse file tree 2 files changed +8
-8
lines changed Original file line number Diff line number Diff line change 1+ * Fixed a thread safety issue in the runtime borrow checker used by mutable pyclass instances on the free-threaded build.
Original file line number Diff line number Diff line change @@ -60,6 +60,7 @@ impl BorrowFlag {
6060 pub ( crate ) const UNUSED : usize = 0 ;
6161 const HAS_MUTABLE_BORROW : usize = usize:: MAX ;
6262 fn increment ( & self ) -> Result < ( ) , PyBorrowError > {
63+ // relaxed is OK because we will read the value again in the compare_exchange
6364 let mut value = self . 0 . load ( Ordering :: Relaxed ) ;
6465 loop {
6566 if value == BorrowFlag :: HAS_MUTABLE_BORROW {
@@ -70,13 +71,13 @@ impl BorrowFlag {
7071 // last atomic load
7172 value,
7273 value + 1 ,
73- Ordering :: Relaxed ,
74+ // reading the value is happens-after a previous write
75+ // writing the new value is happens-after the previous read
76+ Ordering :: AcqRel ,
77+ // relaxed is OK here because we're going to try to read again
7478 Ordering :: Relaxed ,
7579 ) {
7680 Ok ( ..) => {
77- // value has been successfully incremented, we need an acquire fence
78- // so that data this borrow flag protects can be read safely in this thread
79- std:: sync:: atomic:: fence ( Ordering :: Acquire ) ;
8081 break Ok ( ( ) ) ;
8182 }
8283 Err ( changed_value) => {
@@ -87,10 +88,8 @@ impl BorrowFlag {
8788 }
8889 }
8990 fn decrement ( & self ) {
90- // impossible to get into a bad state from here so relaxed
91- // ordering is fine, the decrement only needs to eventually
92- // be visible
93- self . 0 . fetch_sub ( 1 , Ordering :: Relaxed ) ;
91+ // relaxed load is OK but decrements must happen-before the next read
92+ self . 0 . fetch_sub ( 1 , Ordering :: Release ) ;
9493 }
9594}
9695
You can’t perform that action at this time.
0 commit comments