@@ -25,7 +25,7 @@ pub enum Singleton {
25
25
Production ( Container ! [ Send + Sync ] ) ,
26
26
27
27
#[ cfg( debug_assertions) ]
28
- Testing ( parking_lot:: Mutex < std:: collections:: HashMap < String , Container ! [ Send + Sync ] > > ) ,
28
+ Testing ( parking_lot:: RwLock < std:: collections:: HashMap < String , Container ! [ Send + Sync ] > > ) ,
29
29
}
30
30
31
31
unsafe impl Send for Singleton { }
@@ -45,7 +45,7 @@ impl Singleton {
45
45
Some ( name) => name,
46
46
None => panic ! ( "thread doesn't have name" ) ,
47
47
} ;
48
- let guard = c. lock ( ) ;
48
+ let guard = c. read_recursive ( ) ;
49
49
let v: & T = guard
50
50
. get ( thread_name)
51
51
. unwrap_or_else ( || panic ! ( "thread {thread_name} is not initiated" ) )
@@ -65,9 +65,15 @@ impl Singleton {
65
65
Some ( name) => name,
66
66
None => panic ! ( "thread doesn't have name" ) ,
67
67
} ;
68
- let mut guard = c. lock ( ) ;
69
- let c = guard. entry ( thread_name. to_string ( ) ) . or_default ( ) ;
70
- c. set ( value)
68
+ let guard = c. upgradable_read ( ) ;
69
+ match guard. get ( thread_name) {
70
+ Some ( c) => c. set ( value) ,
71
+ None => {
72
+ let mut guard = parking_lot:: RwLockUpgradableReadGuard :: upgrade ( guard) ;
73
+ let c = guard. entry ( thread_name. to_string ( ) ) . or_default ( ) ;
74
+ c. set ( value)
75
+ }
76
+ }
71
77
}
72
78
}
73
79
}
@@ -104,28 +110,21 @@ impl GlobalInstance {
104
110
/// Should only be initiated once and only used in testing.
105
111
#[ cfg( debug_assertions) ]
106
112
pub fn init_testing ( ) {
107
- let _ = GLOBAL . set ( Singleton :: Testing ( parking_lot:: Mutex :: default ( ) ) ) ;
113
+ let _ = GLOBAL . set ( Singleton :: Testing ( parking_lot:: RwLock :: default ( ) ) ) ;
108
114
}
109
115
110
116
/// drop testing global data by thread name.
111
117
///
112
118
/// Should only be used in testing code.
113
119
#[ cfg( debug_assertions) ]
114
120
pub fn drop_testing ( thread_name : & str ) {
115
- use std:: thread;
116
-
117
121
match GLOBAL . wait ( ) {
118
122
Singleton :: Production ( _) => {
119
123
unreachable ! ( "drop_testing should never be called on production global" )
120
124
}
121
125
Singleton :: Testing ( c) => {
122
- // let v = {
123
- // let mut guard = c.lock();
124
- // guard.remove(thread_name)
125
- // };
126
- // // We don't care about if about this container any more, just
127
- // // move to another thread to make sure this call returned ASAP.
128
- // thread::spawn(move || v);
126
+ let mut guard = c. write ( ) ;
127
+ guard. remove ( thread_name) ;
129
128
}
130
129
}
131
130
}
0 commit comments