@@ -79,107 +79,75 @@ EventsExecutor::spin()
7979void
8080EventsExecutor::spin_some (std::chrono::nanoseconds max_duration)
8181{
82- if (spinning.exchange (true )) {
83- throw std::runtime_error (" spin_some() called while already spinning" );
84- }
85- RCLCPP_SCOPE_EXIT (this ->spinning .store (false ););
86-
8782 // In this context a 0 input max_duration means no duration limit
8883 if (std::chrono::nanoseconds (0 ) == max_duration) {
8984 max_duration = timers_manager_->MAX_TIME ;
9085 }
9186
92- auto start = std::chrono::steady_clock::now ();
93-
94- auto max_duration_not_elapsed = [max_duration, start]() {
95- auto elapsed_time = std::chrono::steady_clock::now () - start;
96- return elapsed_time < max_duration;
97- };
98-
99- // Get the number of events ready at this time point
100- std::unique_lock<std::mutex> lock (push_mutex_);
101- size_t available_events_at_tp = events_queue_->size ();
102- lock.unlock ();
103-
104- size_t executed_events = 0 ;
105-
106- // Checks if all events that were ready when spin_some was called, were executed.
107- auto executed_ready_events_at_tp = [executed_events, available_events_at_tp]() {
108- return executed_events >= available_events_at_tp;
109- };
110-
111- // Execute events and timers ready when spin_some was called,
112- // until timeout or no more work available.
113- while (rclcpp::ok (context_) && spinning.load () && max_duration_not_elapsed ()) {
114- // Execute first event from queue if it exists
115- if (!executed_ready_events_at_tp ()) {
116- std::unique_lock<std::mutex> lock (push_mutex_);
117-
118- bool has_event = !events_queue_->empty ();
119-
120- if (has_event) {
121- rmw_listener_event_t event = events_queue_->front ();
122- events_queue_->pop ();
123- // std::cout << "Execute event" << std::endl;
124- this ->execute_event (event);
125- executed_events++;
126- continue ;
127- }
128- }
129-
130- // Execute timer, if was ready at start
131- if (timers_manager_->execute_head_timer_if_ready_at_tp (start)) {
132- continue ;
133- }
134-
135- // If there's no more work available, exit
136- break ;
137- }
87+ return this ->spin_some_impl (max_duration, false );
13888}
13989
14090void
14191EventsExecutor::spin_all (std::chrono::nanoseconds max_duration)
14292{
143- if (spinning. exchange ( true ) ) {
144- throw std::runtime_error ( " spin_all() called while already spinning " );
93+ if (max_duration <= 0ns ) {
94+ throw std::invalid_argument ( " max_duration must be positive " );
14595 }
96+ return this ->spin_some_impl (max_duration, true );
97+ }
14698
147- if (max_duration < 0ns) {
148- throw std::invalid_argument (" max_duration must be positive" );
99+ void
100+ EventsExecutor::spin_some_impl (std::chrono::nanoseconds max_duration, bool exhaustive)
101+ {
102+ if (spinning.exchange (true )) {
103+ throw std::runtime_error (" spin_some() called while already spinning" );
149104 }
150105
151106 RCLCPP_SCOPE_EXIT (this ->spinning .store (false ););
152107
153- // In this context a 0 input max_duration means no duration limit
154- if (std::chrono::nanoseconds (0 ) == max_duration) {
155- max_duration = timers_manager_->MAX_TIME ;
156- }
157-
158108 auto start = std::chrono::steady_clock::now ();
159109
160110 auto max_duration_not_elapsed = [max_duration, start]() {
161111 auto elapsed_time = std::chrono::steady_clock::now () - start;
162112 return elapsed_time < max_duration;
163113 };
164114
165- // Execute timer and events until timeout or no more work available
115+ size_t ready_events_at_start = 0 ;
116+ size_t executed_events = 0 ;
117+
118+ if (!exhaustive) {
119+ // Get the number of events ready at start
120+ std::unique_lock<std::mutex> lock (push_mutex_);
121+ ready_events_at_start = events_queue_->size ();
122+ lock.unlock ();
123+ }
124+
166125 while (rclcpp::ok (context_) && spinning.load () && max_duration_not_elapsed ()) {
167- // Execute first event from queue if it exists
168- {
126+ // Execute first ready event from queue if exists
127+ if (exhaustive || (executed_events < ready_events_at_start)) {
169128 std::unique_lock<std::mutex> lock (push_mutex_);
170-
171129 bool has_event = !events_queue_->empty ();
172130
173131 if (has_event) {
174132 rmw_listener_event_t event = events_queue_->front ();
175133 events_queue_->pop ();
176134 this ->execute_event (event);
135+ executed_events++;
177136 continue ;
178137 }
179138 }
180139
181- // Execute timer, if was ready
182- if (timers_manager_->execute_head_timer ()) {
140+ bool timer_executed;
141+
142+ if (exhaustive) {
143+ // Execute timer if is ready
144+ timer_executed = timers_manager_->execute_head_timer ();
145+ } else {
146+ // Execute timer if was ready at start
147+ timer_executed = timers_manager_->execute_head_timer (start);
148+ }
149+
150+ if (timer_executed) {
183151 continue ;
184152 }
185153
0 commit comments