File tree Expand file tree Collapse file tree 3 files changed +28
-13
lines changed Expand file tree Collapse file tree 3 files changed +28
-13
lines changed Original file line number Diff line number Diff line change @@ -20,11 +20,11 @@ use std::{
20
20
thread:: panicking,
21
21
} ;
22
22
23
+ use super :: Context ;
24
+ use crate :: util:: atomic_incr_if_not_zero;
23
25
#[ cfg( any( test, feature = "leak-detection" ) ) ]
24
26
use collections:: HashMap ;
25
27
26
- use super :: Context ;
27
-
28
28
slotmap:: new_key_type! {
29
29
/// A unique identifier for a entity across the application.
30
30
pub struct EntityId ;
@@ -529,11 +529,10 @@ impl AnyWeakEntity {
529
529
let ref_counts = ref_counts. read ( ) ;
530
530
let ref_count = ref_counts. counts . get ( self . entity_id ) ?;
531
531
532
- // entity_id is in dropped_entity_ids
533
- if ref_count . load ( SeqCst ) == 0 {
532
+ if atomic_incr_if_not_zero ( ref_count ) == 0 {
533
+ // entity_id is in dropped_entity_ids
534
534
return None ;
535
535
}
536
- ref_count. fetch_add ( 1 , SeqCst ) ;
537
536
drop ( ref_counts) ;
538
537
539
538
Some ( AnyEntity {
Original file line number Diff line number Diff line change
1
+ use std:: sync:: atomic:: AtomicUsize ;
2
+ use std:: sync:: atomic:: Ordering :: SeqCst ;
1
3
#[ cfg( any( test, feature = "test-support" ) ) ]
2
4
use std:: time:: Duration ;
3
5
@@ -108,3 +110,18 @@ impl std::fmt::Debug for CwdBacktrace<'_> {
108
110
fmt. finish ( )
109
111
}
110
112
}
113
+
114
+ /// Increment the given atomic counter if it is not zero.
115
+ /// Return the new value of the counter.
116
+ pub ( crate ) fn atomic_incr_if_not_zero ( counter : & AtomicUsize ) -> usize {
117
+ let mut loaded = counter. load ( SeqCst ) ;
118
+ loop {
119
+ if loaded == 0 {
120
+ return 0 ;
121
+ }
122
+ match counter. compare_exchange_weak ( loaded, loaded + 1 , SeqCst , SeqCst ) {
123
+ Ok ( x) => return x + 1 ,
124
+ Err ( actual) => loaded = actual,
125
+ }
126
+ }
127
+ }
Original file line number Diff line number Diff line change @@ -52,6 +52,7 @@ use uuid::Uuid;
52
52
53
53
mod prompts;
54
54
55
+ use crate :: util:: atomic_incr_if_not_zero;
55
56
pub use prompts:: * ;
56
57
57
58
pub ( crate ) const DEFAULT_WINDOW_SIZE : Size < Pixels > = size ( px ( 1024. ) , px ( 700. ) ) ;
@@ -263,15 +264,13 @@ impl FocusHandle {
263
264
pub ( crate ) fn for_id ( id : FocusId , handles : & Arc < FocusMap > ) -> Option < Self > {
264
265
let lock = handles. read ( ) ;
265
266
let ref_count = lock. get ( id) ?;
266
- if ref_count. load ( SeqCst ) == 0 {
267
- None
268
- } else {
269
- ref_count. fetch_add ( 1 , SeqCst ) ;
270
- Some ( Self {
271
- id,
272
- handles : handles. clone ( ) ,
273
- } )
267
+ if atomic_incr_if_not_zero ( ref_count) == 0 {
268
+ return None ;
274
269
}
270
+ Some ( Self {
271
+ id,
272
+ handles : handles. clone ( ) ,
273
+ } )
275
274
}
276
275
277
276
/// Converts this focus handle into a weak variant, which does not prevent it from being released.
You can’t perform that action at this time.
0 commit comments