1- use std:: { panic, sync:: Arc , thread} ;
1+ use std:: {
2+ panic,
3+ sync:: {
4+ Arc ,
5+ atomic:: { AtomicUsize , Ordering } ,
6+ } ,
7+ thread,
8+ } ;
29
310use ctor:: ctor;
411use scope_local:: { ActiveScope , Scope , scope_local} ;
512
613#[ ctor]
7- fn init ( ) {
14+ fn init_percpu ( ) {
815 percpu:: init ( ) ;
916
1017 unsafe { percpu:: write_percpu_reg ( percpu:: percpu_area_base ( 0 ) ) } ;
@@ -14,18 +21,22 @@ fn init() {
1421 println ! ( "per-CPU area size = {}" , percpu:: percpu_area_size( ) ) ;
1522}
1623
17- scope_local ! {
18- static DATA : usize = 0 ;
19- }
20-
2124#[ test]
22- fn global ( ) {
23- assert_eq ! ( * DATA , 0 ) ;
25+ fn scope_init ( ) {
26+ scope_local ! {
27+ static DATA : usize = 42 ;
28+ }
29+ assert_eq ! ( * DATA , 42 ) ;
2430}
2531
2632#[ test]
2733fn scope ( ) {
34+ scope_local ! {
35+ static DATA : usize = 0 ;
36+ }
37+
2838 let mut scope = Scope :: new ( ) ;
39+ assert_eq ! ( * DATA , 0 ) ;
2940 assert_eq ! ( * DATA . scope( & scope) , 0 ) ;
3041
3142 * DATA . scope_mut ( & mut scope) = 42 ;
@@ -35,14 +46,16 @@ fn scope() {
3546 assert_eq ! ( * DATA , 42 ) ;
3647
3748 ActiveScope :: set_global ( ) ;
38- }
39-
40- scope_local ! {
41- static SHARED : Arc <String > = Arc :: new( "qwq" . to_string( ) ) ;
49+ assert_eq ! ( * DATA , 0 ) ;
50+ assert_eq ! ( * DATA . scope( & scope) , 42 ) ;
4251}
4352
4453#[ test]
45- fn shared ( ) {
54+ fn scope_drop ( ) {
55+ scope_local ! {
56+ static SHARED : Arc <( ) > = Arc :: new( ( ) ) ;
57+ }
58+
4659 assert_eq ! ( Arc :: strong_count( & SHARED ) , 1 ) ;
4760
4861 {
@@ -54,32 +67,45 @@ fn shared() {
5467 }
5568
5669 assert_eq ! ( Arc :: strong_count( & SHARED ) , 1 ) ;
70+ }
71+
72+ #[ test]
73+ fn scope_panic_unwind_drop ( ) {
74+ scope_local ! {
75+ static SHARED : Arc <( ) > = Arc :: new( ( ) ) ;
76+ }
5777
5878 let panic = panic:: catch_unwind ( || {
5979 let mut scope = Scope :: new ( ) ;
6080 * SHARED . scope_mut ( & mut scope) = SHARED . clone ( ) ;
81+ assert_eq ! ( Arc :: strong_count( & SHARED ) , 2 ) ;
6182 panic ! ( "panic" ) ;
6283 } ) ;
6384 assert ! ( panic. is_err( ) ) ;
6485
6586 assert_eq ! ( Arc :: strong_count( & SHARED ) , 1 ) ;
6687}
6788
68- scope_local ! {
69- static T_SHARED : Arc <String > = Arc :: new( "qwq" . to_string( ) ) ;
70- }
71-
7289#[ test]
73- fn threads_shared ( ) {
74- assert_eq ! ( Arc :: strong_count( & SHARED ) , 1 ) ;
90+ fn thread_share_item ( ) {
91+ scope_local ! {
92+ static SHARED : Arc <( ) > = Arc :: new( ( ) ) ;
93+ }
7594
7695 let handles: Vec < _ > = ( 0 ..10 )
7796 . map ( |_| {
7897 thread:: spawn ( move || {
98+ let global = & * SHARED ;
99+
79100 let mut scope = Scope :: new ( ) ;
80- * T_SHARED . scope_mut ( & mut scope) = T_SHARED . clone ( ) ;
81- assert ! ( Arc :: strong_count( & T_SHARED ) >= 2 ) ;
82- assert_eq ! ( * T_SHARED , Arc :: new( "qwq" . to_string( ) ) ) ;
101+ * SHARED . scope_mut ( & mut scope) = global. clone ( ) ;
102+
103+ unsafe { ActiveScope :: set ( & scope) } ;
104+
105+ assert ! ( Arc :: strong_count( & SHARED ) >= 2 ) ;
106+ assert ! ( Arc :: ptr_eq( & SHARED , global) ) ;
107+
108+ ActiveScope :: set_global ( ) ;
83109 } )
84110 } )
85111 . collect ( ) ;
@@ -88,35 +114,44 @@ fn threads_shared() {
88114 h. join ( ) . unwrap ( ) ;
89115 }
90116
91- assert_eq ! ( Arc :: strong_count( & T_SHARED ) , 1 ) ;
117+ assert_eq ! ( Arc :: strong_count( & SHARED ) , 1 ) ;
118+ }
92119
93- {
94- let mut scope = Scope :: new ( ) ;
95- * T_SHARED . scope_mut ( & mut scope) = T_SHARED . clone ( ) ;
96- let scope = Arc :: new ( scope) ;
97-
98- let handles: Vec < _ > = ( 0 ..10 )
99- . map ( |_| {
100- let scope = scope. clone ( ) ;
101- thread:: spawn ( move || {
102- unsafe { ActiveScope :: set ( & scope) } ;
103- assert_eq ! ( Arc :: strong_count( & T_SHARED ) , 2 ) ;
104- assert_eq ! ( * T_SHARED , Arc :: new( "qwq" . to_string( ) ) ) ;
105- ActiveScope :: set_global ( ) ;
106- } )
120+ #[ test]
121+ fn thread_share_scope ( ) {
122+ scope_local ! {
123+ static SHARED : Arc <( ) > = Arc :: new( ( ) ) ;
124+ }
125+
126+ let scope = Arc :: new ( Scope :: new ( ) ) ;
127+
128+ let handles: Vec < _ > = ( 0 ..10 )
129+ . map ( |_| {
130+ let scope = scope. clone ( ) ;
131+ thread:: spawn ( move || {
132+ unsafe { ActiveScope :: set ( & scope) } ;
133+ assert_eq ! ( Arc :: strong_count( & SHARED ) , 1 ) ;
134+ assert ! ( Arc :: ptr_eq( & SHARED , & SHARED . scope( & scope) ) ) ;
135+ ActiveScope :: set_global ( ) ;
107136 } )
108- . collect ( ) ;
137+ } )
138+ . collect ( ) ;
109139
110- for h in handles {
111- h. join ( ) . unwrap ( ) ;
112- }
140+ for h in handles {
141+ h. join ( ) . unwrap ( ) ;
113142 }
114143
115- assert_eq ! ( Arc :: strong_count( & T_SHARED ) , 1 ) ;
144+ assert_eq ! ( Arc :: strong_count( & SHARED ) , 1 ) ;
145+ assert_eq ! ( Arc :: strong_count( & SHARED . scope( & scope) ) , 1 ) ;
116146}
117147
118148#[ test]
119- fn isolation ( ) {
149+ fn thread_isolation ( ) {
150+ scope_local ! {
151+ static DATA : usize = 0 ;
152+ static DATA2 : AtomicUsize = AtomicUsize :: new( 0 ) ;
153+ }
154+
120155 let handles: Vec < _ > = ( 0 ..10 )
121156 . map ( |i| {
122157 thread:: spawn ( move || {
@@ -126,6 +161,8 @@ fn isolation() {
126161 unsafe { ActiveScope :: set ( & scope) } ;
127162 assert_eq ! ( * DATA , i) ;
128163
164+ DATA2 . store ( i, Ordering :: Relaxed ) ;
165+
129166 ActiveScope :: set_global ( ) ;
130167 } )
131168 } )
@@ -136,21 +173,5 @@ fn isolation() {
136173 }
137174
138175 assert_eq ! ( * DATA , 0 ) ;
139- }
140-
141- #[ test]
142- fn nested ( ) {
143- let mut outer = Scope :: new ( ) ;
144- unsafe { ActiveScope :: set ( & outer) } ;
145- * DATA . scope_mut ( & mut outer) = 1 ;
146-
147- let mut inner = Scope :: new ( ) ;
148- unsafe { ActiveScope :: set ( & inner) } ;
149- * DATA . scope_mut ( & mut inner) = 2 ;
150- assert_eq ! ( * DATA , 2 ) ;
151-
152- unsafe { ActiveScope :: set ( & outer) } ;
153- assert_eq ! ( * DATA , 1 ) ;
154-
155- ActiveScope :: set_global ( ) ;
176+ assert_eq ! ( DATA2 . load( Ordering :: Relaxed ) , 0 ) ;
156177}
0 commit comments