File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -50,7 +50,16 @@ struct Scheduler {
5050 if (microseconds == 0 ) [[unlikely]] microseconds = 1 ;
5151 return register_task (microseconds, func, false );
5252 }
53- static inline void cancel_timeout (uint8_t id) { unregister_task (id); }
53+ static inline void cancel_timeout (uint8_t id) {
54+ /* NOTE: This does not fix this case:
55+ 1. id = set_timeout(x, func)
56+ 2. timeout ends, func gets called and removed internally
57+ 3. id_2 = set_timeout(y, func_2) // id will be equal to id_2
58+ 4. clear_timeout(id) -> will remove the second timeout
59+ */
60+ if (!tasks_[id].repeating ) return ;
61+ unregister_task (id);
62+ }
5463
5564 // static void global_timer_callback();
5665
Original file line number Diff line number Diff line change @@ -94,3 +94,22 @@ TEST_F(SchedulerTests, GlobalTickOverflow) {
9494 // 100 ticks /20 ticks/task = 5 executions.
9595 EXPECT_EQ (count, 5 );
9696}
97+
98+ TEST_F (SchedulerTests, TimeoutClearAddTask) {
99+ uint8_t timeout_id = Scheduler::set_timeout (10 , &fake_workload);
100+ Scheduler::start ();
101+
102+ constexpr int NUM_TICKS = 100 ;
103+ for (int i = 0 ; i < NUM_TICKS; i++) {
104+ TIM2_BASE->CNT ++;
105+ Scheduler::update ();
106+ }
107+
108+ // timeout is already done here
109+ uint8_t task_id = Scheduler::register_task (20 , &fake_workload);
110+
111+ // after timeout, cancel task
112+ Scheduler::cancel_timeout (timeout_id);
113+
114+ EXPECT_EQ (Scheduler::active_task_count_, 1 );
115+ }
You can’t perform that action at this time.
0 commit comments