25
25
#include " coredecls.h"
26
26
27
27
using mSchedFuncT = Delegate<void (), void *>;
28
+ // queue specialization: cache erased nodes, call each once next round.
28
29
MultiDelegate<mSchedFuncT , true > schedFuncs;
29
30
30
31
class mRecFuncT : public Delegate <bool (), void *>
@@ -36,13 +37,15 @@ class mRecFuncT : public Delegate<bool(), void*>
36
37
using base_type::operator =;
37
38
esp8266::polledTimeout::periodicFastUs callNow;
38
39
Delegate<bool (), void *> alarm = nullptr ;
40
+ // return true to keep, false to erase.
39
41
bool IRAM_ATTR operator ()()
40
42
{
41
43
const bool wakeup = alarm && alarm ();
42
44
bool callNow = this ->callNow ;
43
45
return !(wakeup || callNow) || base_type::operator ()();
44
46
}
45
47
};
48
+ // non-queue specialization: heap new/delete, use explicit erase.
46
49
MultiDelegate<mRecFuncT > recFuncs;
47
50
48
51
IRAM_ATTR // (not only) called from ISR
@@ -74,5 +77,25 @@ void run_scheduled_functions()
74
77
75
78
void run_scheduled_recurrent_functions ()
76
79
{
77
- recFuncs ();
80
+ auto it = recFuncs.begin ();
81
+ if (!it)
82
+ return ;
83
+
84
+ static std::atomic<bool > fence (false );
85
+ // prevent recursive calls
86
+ if (fence.load ()) return ;
87
+ fence.store (true );
88
+
89
+ auto end = recFuncs.end ();
90
+ do
91
+ {
92
+ if ((*it)())
93
+ ++it;
94
+ else
95
+ it = recFuncs.erase (it);
96
+ // running callbacks might last too long for watchdog etc.
97
+ optimistic_yield (10000 );
98
+ } while (it != end);
99
+
100
+ fence.store (false );
78
101
}
0 commit comments