| 1 | #include <thread/workqueue.h> |
| 2 | #include <time/timer.h> |
| 3 | |
| 4 | static 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 | |
| 14 | void 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 | |
| 21 | bool 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 | |
| 33 | bool delayed_work_schedule(struct delayed_work *dwork, time_ms_t delay_ms) { |
| 34 | return delayed_work_schedule_on(NULL, dwork, delay_ms); |
| 35 | } |
| 36 | |
| 37 | bool delayed_work_cancel(struct delayed_work *dwork) { |
| 38 | return timer_delete(timer: &dwork->timer); |
| 39 | } |
| 40 | |
| 41 | bool delayed_work_cancel_sync(struct delayed_work *dwork) { |
| 42 | return timer_delete_sync(timer: &dwork->timer); |
| 43 | } |
| 44 | |