@@ -114,32 +114,39 @@ impl WaitSet {
114
114
} )
115
115
}
116
116
} ;
117
+
117
118
// SAFETY: The comments in rcl mention "This function cannot operate on the same wait set
118
119
// in multiple threads, and the wait sets may not share content."
119
- // We cannot currently guarantee that the wait sets may not share content, but it is
120
- // mentioned in the doc comment for `add_subscription`.
121
- // Also, the rcl_wait_set is obviously valid.
122
- match unsafe { rcl_wait ( & mut self . handle . rcl_wait_set , timeout_ns) } . ok ( ) {
123
- Ok ( _) => ( ) ,
120
+ // * The we have exclusive access to rcl_wait_set because this is a
121
+ // mutable borrow of WaitSet, which houses rcl_wait_set.
122
+ // * We guarantee that the wait sets do not share content by funneling
123
+ // the waitable of each primitive to one (and only one) WaitSet when
124
+ // the primitive gets constructed. The waitables are never allowed to
125
+ // move between wait sets.
126
+ let r = match unsafe { rcl_wait ( & mut self . handle . rcl_wait_set , timeout_ns) } . ok ( ) {
127
+ Ok ( _) => Ok ( ( ) ) ,
124
128
Err ( error) => match error {
125
129
RclrsError :: RclError { code, msg } => match code {
126
- RclReturnCode :: WaitSetEmpty => ( ) ,
127
- _ => return Err ( RclrsError :: RclError { code, msg } ) ,
130
+ RclReturnCode :: WaitSetEmpty => Ok ( ( ) ) ,
131
+ _ => Err ( RclrsError :: RclError { code, msg } ) ,
128
132
} ,
129
- _ => return Err ( error) ,
133
+ _ => Err ( error) ,
130
134
} ,
131
- }
135
+ } ;
132
136
133
137
// Remove any waitables that are no longer being used
134
138
for waitable in self . primitives . values_mut ( ) {
135
139
waitable. retain ( |w| w. in_use ( ) ) ;
136
140
}
137
141
138
- // For the remaining entities, check if they were activated and then run
139
- // the callback for those that were.
140
- for waiter in self . primitives . values_mut ( ) . flat_map ( |v| v) {
141
- if waiter. is_ready ( & self . handle . rcl_wait_set ) {
142
- f ( & mut * waiter. primitive ) ?;
142
+ // Do not check the readiness if an error was reported.
143
+ if !r. is_err ( ) {
144
+ // For the remaining entities, check if they were activated and then run
145
+ // the callback for those that were.
146
+ for waiter in self . primitives . values_mut ( ) . flat_map ( |v| v) {
147
+ if waiter. is_ready ( & self . handle . rcl_wait_set ) {
148
+ f ( & mut * waiter. primitive ) ?;
149
+ }
143
150
}
144
151
}
145
152
@@ -160,7 +167,7 @@ impl WaitSet {
160
167
) ;
161
168
}
162
169
163
- Ok ( ( ) )
170
+ r
164
171
}
165
172
166
173
/// Get a count of the different kinds of entities in the wait set.
0 commit comments