@@ -5,6 +5,7 @@ use crate::{
5
5
use crate :: { Node , ParameterValue , QoSProfile , Subscription , QOS_PROFILE_CLOCK } ;
6
6
use rosgraph_msgs:: msg:: Clock as ClockMsg ;
7
7
use std:: fmt;
8
+ use std:: sync:: atomic:: { AtomicBool , Ordering } ;
8
9
use std:: sync:: { Arc , Mutex } ;
9
10
10
11
/// Time source for a node that drives the attached clocks.
@@ -17,7 +18,7 @@ pub struct TimeSource {
17
18
// TODO(luca) implement clock threads, for now will run in main thread
18
19
_use_clock_thread : bool ,
19
20
// TODO(luca) Update this with parameter callbacks for use_sim_time
20
- _ros_time_active : Arc < Mutex < bool > > ,
21
+ _ros_time_active : Arc < AtomicBool > ,
21
22
_clock_subscription : Option < Arc < Subscription < ClockMsg > > > ,
22
23
_last_time_msg : Arc < Mutex < Option < ClockMsg > > > ,
23
24
}
@@ -77,7 +78,7 @@ impl TimeSourceBuilder {
77
78
_clocks : Arc :: new ( Mutex :: new ( vec ! [ ] ) ) ,
78
79
_clock_qos : self . clock_qos ,
79
80
_use_clock_thread : self . use_clock_thread ,
80
- _ros_time_active : Arc :: new ( Mutex :: new ( false ) ) ,
81
+ _ros_time_active : Arc :: new ( AtomicBool :: new ( false ) ) ,
81
82
_clock_subscription : None ,
82
83
_last_time_msg : Arc :: new ( Mutex :: new ( None ) ) ,
83
84
} ;
@@ -109,7 +110,9 @@ impl TimeSource {
109
110
/// Attaches the given clock to the `TimeSource`, enabling the `TimeSource` to control it.
110
111
pub fn attach_clock ( & self , clock : Arc < Clock > ) -> Result < ( ) , ClockMismatchError > {
111
112
let clock_type = clock. clock_type ( ) ;
112
- if !matches ! ( clock_type, ClockType :: RosTime ) && * self . _ros_time_active . lock ( ) . unwrap ( ) {
113
+ if !matches ! ( clock_type, ClockType :: RosTime )
114
+ && self . _ros_time_active . load ( Ordering :: Relaxed )
115
+ {
113
116
return Err ( ClockMismatchError ( clock_type) ) ;
114
117
}
115
118
if let Some ( last_msg) = self . _last_time_msg . lock ( ) . unwrap ( ) . clone ( ) {
@@ -155,9 +158,17 @@ impl TimeSource {
155
158
}
156
159
157
160
fn set_ros_time ( & mut self , enable : bool ) -> Result < ( ) , RclrsError > {
158
- let mut ros_time_active = self . _ros_time_active . lock ( ) . unwrap ( ) ;
159
- if enable != * ros_time_active {
160
- * ros_time_active = enable;
161
+ let updated = self
162
+ . _ros_time_active
163
+ . fetch_update ( Ordering :: Relaxed , Ordering :: Relaxed , |prev| {
164
+ if prev != enable {
165
+ Some ( enable)
166
+ } else {
167
+ None
168
+ }
169
+ } )
170
+ . is_ok ( ) ;
171
+ if updated {
161
172
for clock in self . _clocks . lock ( ) . unwrap ( ) . iter ( ) {
162
173
clock. set_ros_time ( enable) ;
163
174
}
@@ -189,7 +200,7 @@ impl TimeSource {
189
200
"/clock" ,
190
201
self . _clock_qos ,
191
202
move |msg : ClockMsg | {
192
- if * ros_time_active. lock ( ) . unwrap ( ) {
203
+ if ros_time_active. load ( Ordering :: Relaxed ) {
193
204
let nanoseconds: i64 =
194
205
( msg. clock . sec as i64 * 1_000_000_000 ) + msg. clock . nanosec as i64 ;
195
206
* last_time_msg. lock ( ) . unwrap ( ) = Some ( msg) ;
0 commit comments