diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2020-05-14 20:21:52 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2020-08-13 13:55:22 +0200 |
commit | 04e54a0cf635de24656e7818cddb25333d284c79 (patch) | |
tree | 2be5c9248c4955c2637ef0a49313517a1a9a05f1 /common/poller.c | |
parent | 94b264aca5685aeba5fb6babc097d64b78478a11 (diff) | |
download | barebox-04e54a0cf635de24656e7818cddb25333d284c79.tar.gz barebox-04e54a0cf635de24656e7818cddb25333d284c79.tar.xz |
Add workqueues
Some code wants to run arbitrary code in the background, examples are
fastboot and ratp. Currently this is implemented in pollers. The problem
with this is that pollers are executed whenever is_timeout() is called
which may happen anywhere in the code. With this we can never tell which
resources are currently in use when the poller is executed.
This adds a work queue interface which is specifically designed to
trigger doing work in a context where it's safe to run arbitrary commands.
Code in pollers can attach work to a work queue which is at that time
only queued up. A new slice, the command slice, is added which by
default is acquired. It is only released at places where the shell waits
for input. When during this time pollers are executed the queued up
works are done before running the registered pollers.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'common/poller.c')
-rw-r--r-- | common/poller.c | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/common/poller.c b/common/poller.c index 95f828b439..7b1b92714c 100644 --- a/common/poller.c +++ b/common/poller.c @@ -12,6 +12,8 @@ #include <param.h> #include <poller.h> #include <clock.h> +#include <work.h> +#include <slice.h> static LIST_HEAD(poller_list); static int poller_active; @@ -110,15 +112,22 @@ int poller_async_unregister(struct poller_async *pa) void poller_call(void) { struct poller_struct *poller, *tmp; + bool run_workqueues = !slice_acquired(&command_slice); if (poller_active) return; + command_slice_acquire(); + + if (run_workqueues) + wq_do_all_works(); + poller_active = 1; list_for_each_entry_safe(poller, tmp, &poller_list, list) poller->func(poller); + command_slice_release(); poller_active = 0; } |