summaryrefslogtreecommitdiffstats
path: root/common/poller.c
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2020-05-14 20:21:52 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2020-08-13 13:55:22 +0200
commit04e54a0cf635de24656e7818cddb25333d284c79 (patch)
tree2be5c9248c4955c2637ef0a49313517a1a9a05f1 /common/poller.c
parent94b264aca5685aeba5fb6babc097d64b78478a11 (diff)
downloadbarebox-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.c9
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;
}