diff options
-rw-r--r-- | common/cyclic.c | 17 | ||||
-rw-r--r-- | doc/develop/cyclic.rst | 13 |
2 files changed, 30 insertions, 0 deletions
diff --git a/common/cyclic.c b/common/cyclic.c index b695f092f52..ec952a01ee1 100644 --- a/common/cyclic.c +++ b/common/cyclic.c @@ -28,9 +28,23 @@ struct hlist_head *cyclic_get_list(void) return (struct hlist_head *)&gd->cyclic_list; } +static bool cyclic_is_registered(const struct cyclic_info *cyclic) +{ + const struct cyclic_info *c; + + hlist_for_each_entry(c, cyclic_get_list(), list) { + if (c == cyclic) + return true; + } + + return false; +} + void cyclic_register(struct cyclic_info *cyclic, cyclic_func_t func, uint64_t delay_us, const char *name) { + cyclic_unregister(cyclic); + memset(cyclic, 0, sizeof(*cyclic)); /* Store values in struct */ @@ -43,6 +57,9 @@ void cyclic_register(struct cyclic_info *cyclic, cyclic_func_t func, void cyclic_unregister(struct cyclic_info *cyclic) { + if (!cyclic_is_registered(cyclic)) + return; + hlist_del(&cyclic->list); } diff --git a/doc/develop/cyclic.rst b/doc/develop/cyclic.rst index 6f1da6f0d9b..a99b17052f5 100644 --- a/doc/develop/cyclic.rst +++ b/doc/develop/cyclic.rst @@ -54,3 +54,16 @@ responsible for calling all registered cyclic functions, into the common schedule() function. This guarantees that cyclic_run() is executed very often, which is necessary for the cyclic functions to get scheduled and executed at their configured periods. + +Idempotence +----------- + +Both the cyclic_register() and cyclic_unregister() functions are safe +to call on any struct cyclic_info, regardless of whether that instance +is already registered or not. + +More specifically, calling cyclic_unregister() with a cyclic_info +which is not currently registered is a no-op, while calling +cyclic_register() with a cyclic_info which is currently registered +results in it being automatically unregistered, and then registered +with the new callback function and timeout parameters. |