mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-25 20:02:37 +03:00
scheduled functions: fixes (#6137)
* scheduled functions: properly reset structure * fence against recursion, rename variables for clarity * update comments
This commit is contained in:
parent
0a8f2a13a6
commit
09f6b87ef5
@ -33,6 +33,7 @@ static scheduled_fn_t* get_fn_unsafe()
|
||||
result = sUnused;
|
||||
sUnused = sUnused->mNext;
|
||||
result->mNext = nullptr;
|
||||
result->callNow.reset(esp8266::polledTimeout::periodicFastUs::alwaysExpired);
|
||||
}
|
||||
// if no unused items, and count not too high, allocate a new one
|
||||
else if (sCount < SCHEDULED_FN_MAX_COUNT)
|
||||
@ -100,32 +101,43 @@ void run_scheduled_functions()
|
||||
// its purpose is that it is never called from an interrupt
|
||||
// (always on cont stack).
|
||||
|
||||
scheduled_fn_t* lastRecurring = nullptr;
|
||||
scheduled_fn_t* toCall = sFirst;
|
||||
while (toCall)
|
||||
static bool fence = false;
|
||||
{
|
||||
scheduled_fn_t* item = toCall;
|
||||
toCall = toCall->mNext;
|
||||
if (item->callNow)
|
||||
InterruptLock lockAllInterruptsInThisScope;
|
||||
if (fence)
|
||||
// prevent recursive calls from yield()
|
||||
return;
|
||||
fence = true;
|
||||
}
|
||||
|
||||
scheduled_fn_t* lastRecurring = nullptr;
|
||||
scheduled_fn_t* nextCall = sFirst;
|
||||
while (nextCall)
|
||||
{
|
||||
scheduled_fn_t* toCall = nextCall;
|
||||
nextCall = nextCall->mNext;
|
||||
if (toCall->callNow)
|
||||
{
|
||||
if (item->mFunc())
|
||||
if (toCall->mFunc())
|
||||
{
|
||||
lastRecurring = item;
|
||||
lastRecurring = toCall;
|
||||
}
|
||||
else
|
||||
{
|
||||
InterruptLock lockAllInterruptsInThisScope;
|
||||
|
||||
if (sFirst == item)
|
||||
if (sFirst == toCall)
|
||||
sFirst = sFirst->mNext;
|
||||
else if (lastRecurring)
|
||||
lastRecurring->mNext = item->mNext;
|
||||
lastRecurring->mNext = toCall->mNext;
|
||||
|
||||
if (sLast == item)
|
||||
if (sLast == toCall)
|
||||
sLast = lastRecurring;
|
||||
|
||||
recycle_fn_unsafe(item);
|
||||
recycle_fn_unsafe(toCall);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fence = false;
|
||||
}
|
||||
|
@ -3,25 +3,38 @@
|
||||
|
||||
#include <functional>
|
||||
|
||||
// This API is stabilizing
|
||||
// Function signatures may change, internal queue will remain FIFO.
|
||||
//
|
||||
// * Add the given lambda to a fifo list of lambdas, which is run when
|
||||
// - `loop` function returns,
|
||||
// - or `yield` is called,
|
||||
// - or `run_scheduled_functions` is called.
|
||||
//
|
||||
// * Use lambdas to pass arguments to a function, or call a class/static
|
||||
// member function.
|
||||
//
|
||||
// * Please ensure variables or instances used from inside lambda will exist
|
||||
// when lambda is later called
|
||||
//
|
||||
// * There is no mechanism for cancelling scheduled functions.
|
||||
//
|
||||
// * `yield` can be called from inside lambdas
|
||||
//
|
||||
// * Returns false if the number of scheduled functions exceeds
|
||||
// SCHEDULED_FN_MAX_COUNT.
|
||||
|
||||
#define SCHEDULED_FN_MAX_COUNT 32
|
||||
|
||||
// This API was not considered stable but is now stabilizing.
|
||||
// Function signatures may change, queue must stay FIFO.
|
||||
// You have been warned.
|
||||
|
||||
// Run given function ONCE next time `loop` function returns,
|
||||
// or `yield` is called,
|
||||
// or `run_scheduled_functions` is called.
|
||||
// Use std::bind to pass arguments to a function, or call a class member function.
|
||||
// Note: there is no mechanism for cancelling scheduled functions.
|
||||
// Keep that in mind when binding functions to objects which may have short lifetime.
|
||||
// Returns false if the number of scheduled functions exceeds SCHEDULED_FN_MAX_COUNT.
|
||||
// * Run the lambda only once next time
|
||||
//bool schedule_function(std::function<void(void)>&& fn);
|
||||
bool schedule_function(const std::function<void(void)>& fn);
|
||||
|
||||
// Run given function periodically about every <repeat_us> microseconds until it returns false.
|
||||
// Note that it may be more than <repeat_us> microseconds between calls if `yield` is not called
|
||||
// frequently, and therefore should not be used for timing critical operations.
|
||||
// * Run the lambda periodically about every <repeat_us> microseconds until
|
||||
// it returns false.
|
||||
// * Note that it may be more than <repeat_us> microseconds between calls if
|
||||
// `yield` is not called frequently, and therefore should not be used for
|
||||
// timing critical operations.
|
||||
//bool schedule_function_us(std::function<bool(void)>&& fn, uint32_t repeat_us);
|
||||
bool schedule_function_us(const std::function<bool(void)>& fn, uint32_t repeat_us);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user