@@ -10,38 +10,28 @@ pub mod utils;
10
10
pub const ACQUIRE_TIMEOUT_MS : u64 = 100 ;
11
11
pub const HOLD_TIMEOUT_MS : u64 = 100 ;
12
12
13
- pub struct TimedRwReadGuard < ' a , T : ? Sized > {
14
- pub inner : tokio :: sync :: RwLockReadGuard < ' a , T > ,
13
+ pub struct TimedGuard < T > {
14
+ pub inner : T ,
15
15
pub acquisition_line : u32 ,
16
16
pub acquisition_file : & ' static str ,
17
17
pub acquisition_time : std:: time:: Instant ,
18
18
pub sleep_task : tokio:: task:: JoinHandle < ( ) > ,
19
19
}
20
20
21
- async fn sleep_then_log ( file : & ' static str , line : u32 ) {
22
- tokio:: time:: sleep ( std:: time:: Duration :: from_millis ( HOLD_TIMEOUT_MS ) ) . await ;
23
- log:: warn!(
24
- "[{}:{}] lock held for over {}ms, not yet released" ,
25
- file,
26
- line,
27
- HOLD_TIMEOUT_MS . to_string( )
28
- ) ;
29
- }
30
-
31
- impl < ' a , T : ?Sized > TimedRwReadGuard < ' a , T > {
21
+ impl < T > TimedGuard < T > {
32
22
pub async fn new (
33
- inner : tokio :: sync :: RwLockReadGuard < ' a , T > ,
23
+ inner : T ,
34
24
acquisition_line : u32 ,
35
25
acquisition_file : & ' static str ,
36
- ) -> TimedRwReadGuard < ' a , T > {
26
+ ) -> TimedGuard < T > {
37
27
let now = std:: time:: Instant :: now ( ) ;
38
28
let move_line = acquisition_line;
39
29
let move_file = acquisition_file;
40
30
let handle = tokio:: spawn ( async move {
41
31
sleep_then_log ( move_file, move_line) . await ;
42
32
} ) ;
43
33
44
- TimedRwReadGuard {
34
+ TimedGuard {
45
35
inner,
46
36
acquisition_line,
47
37
acquisition_file,
@@ -51,15 +41,21 @@ impl<'a, T: ?Sized> TimedRwReadGuard<'a, T> {
51
41
}
52
42
}
53
43
54
- impl < ' a , T > std:: ops:: Deref for TimedRwReadGuard < ' a , T > {
55
- type Target = tokio :: sync :: RwLockReadGuard < ' a , T > ;
44
+ impl < T > std:: ops:: Deref for TimedGuard < T > {
45
+ type Target = T ;
56
46
57
47
fn deref ( & self ) -> & Self :: Target {
58
48
& self . inner
59
49
}
60
50
}
61
51
62
- impl < ' a , T : ?Sized > Drop for TimedRwReadGuard < ' a , T > {
52
+ impl < T > std:: ops:: DerefMut for TimedGuard < T > {
53
+ fn deref_mut ( & mut self ) -> & mut Self :: Target {
54
+ & mut self . inner
55
+ }
56
+ }
57
+
58
+ impl < T > Drop for TimedGuard < T > {
63
59
fn drop ( & mut self ) {
64
60
self . sleep_task . abort ( ) ;
65
61
let held_for = self . acquisition_time . elapsed ( ) . as_millis ( ) ;
@@ -74,9 +70,19 @@ impl<'a, T: ?Sized> Drop for TimedRwReadGuard<'a, T> {
74
70
}
75
71
}
76
72
73
+ async fn sleep_then_log ( file : & ' static str , line : u32 ) {
74
+ tokio:: time:: sleep ( std:: time:: Duration :: from_millis ( HOLD_TIMEOUT_MS ) ) . await ;
75
+ log:: warn!(
76
+ "[{}:{}] lock held for over {}ms, not yet released" ,
77
+ file,
78
+ line,
79
+ HOLD_TIMEOUT_MS . to_string( )
80
+ ) ;
81
+ }
82
+
77
83
#[ macro_export]
78
- macro_rules! rw_read {
79
- ( $lock_name: expr) => { {
84
+ macro_rules! inner_rw {
85
+ ( $meth : ident , $ lock_name: expr) => { {
80
86
let acquire_timeout = std:: time:: Duration :: from_millis( $crate:: ACQUIRE_TIMEOUT_MS ) ;
81
87
let sleep = tokio:: time:: sleep( acquire_timeout) ;
82
88
tokio:: pin!( sleep) ;
@@ -95,7 +101,7 @@ macro_rules! rw_read {
95
101
) ;
96
102
did_log = true ;
97
103
}
98
- guard = $lock_name. read ( ) => {
104
+ guard = $lock_name. $meth ( ) => {
99
105
if did_log {
100
106
let wait_time = now. elapsed( ) . as_millis( ) ;
101
107
log:: warn!(
@@ -106,7 +112,7 @@ macro_rules! rw_read {
106
112
) ;
107
113
}
108
114
109
- let wrapped = $crate:: TimedRwReadGuard :: new(
115
+ let wrapped = $crate:: TimedGuard :: new(
110
116
guard, std:: line!( ) , std:: file!( ) ,
111
117
) . await ;
112
118
break wrapped;
@@ -119,24 +125,13 @@ macro_rules! rw_read {
119
125
#[ macro_export]
120
126
macro_rules! rw_write {
121
127
( $lock_name: expr) => { {
122
- let acquire_timeout = std :: time :: Duration :: from_millis ( $crate:: ACQUIRE_TIMEOUT_MS ) ;
123
- let sleep = tokio :: time :: sleep ( acquire_timeout ) ;
124
- tokio :: pin! ( sleep ) ;
128
+ $crate:: inner_rw! ( write , $lock_name )
129
+ } }
130
+ }
125
131
126
- loop {
127
- tokio:: select! {
128
- _ = & mut sleep, if !sleep. is_elapsed( ) => {
129
- log:: warn!(
130
- "[{}:{}] took more than {} ms to acquire lock" ,
131
- std:: file!( ) ,
132
- std:: line!( ) ,
133
- $crate:: ACQUIRE_TIMEOUT_MS ,
134
- ) ;
135
- }
136
- guard = $lock_name. write( ) => {
137
- break guard;
138
- }
139
- }
140
- }
141
- } } ;
132
+ #[ macro_export]
133
+ macro_rules! rw_read {
134
+ ( $lock_name: expr) => { {
135
+ $crate:: inner_rw!( read, $lock_name)
136
+ } }
142
137
}
0 commit comments