1#include <thread/workqueue.h>
2#include <time/timer.h>
3
4static void delayed_work_timer_cb(struct timer *t) {
5 struct delayed_work *dwork = t->data;
6 if (dwork->wq) {
7 workqueue_enqueue(queue: dwork->wq, work: &dwork->work);
8 } else {
9 enum workqueue_error err = workqueue_add(work: &dwork->work);
10 unused(err);
11 }
12}
13
14void delayed_work_init(struct delayed_work *dwork, work_function fn,
15 struct work_args args) {
16 work_init(work: &dwork->work, fn, args);
17 dwork->wq = NULL;
18 timer_init(timer: &dwork->timer, func: delayed_work_timer_cb, data: dwork);
19}
20
21bool delayed_work_schedule_on(struct workqueue *wq, struct delayed_work *dwork,
22 time_ms_t delay_ms) {
23 dwork->wq = wq;
24 if (delay_ms == 0) {
25 if (wq)
26 return workqueue_enqueue(queue: wq, work: &dwork->work) == WORKQUEUE_ERROR_OK;
27 return workqueue_add(work: &dwork->work) == WORKQUEUE_ERROR_OK;
28 }
29
30 return timer_modify(timer: &dwork->timer, new: timer_delta_us(MS_TO_US(delay_ms)));
31}
32
33bool delayed_work_schedule(struct delayed_work *dwork, time_ms_t delay_ms) {
34 return delayed_work_schedule_on(NULL, dwork, delay_ms);
35}
36
37bool delayed_work_cancel(struct delayed_work *dwork) {
38 return timer_delete(timer: &dwork->timer);
39}
40
41bool delayed_work_cancel_sync(struct delayed_work *dwork) {
42 return timer_delete_sync(timer: &dwork->timer);
43}
44