runqueue: add a function that allows adding jobs to the front of the runqueue
[project/libubox.git] / runqueue.h
1 /*
2  * runqueue.c - a simple task queueing/completion tracking helper
3  *
4  * Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
5  *
6  * Permission to use, copy, modify, and/or distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18
19 #ifndef __LIBUBOX_RUNQUEUE_H
20 #define __LIBUBOX_RUNQUEUE_H
21
22 #include "list.h"
23 #include "safe_list.h"
24 #include "uloop.h"
25
26 struct runqueue;
27 struct runqueue_task;
28 struct runqueue_task_type;
29
30 struct runqueue {
31         struct safe_list tasks_active;
32         struct safe_list tasks_inactive;
33         struct uloop_timeout timeout;
34
35         int running_tasks;
36         int max_running_tasks;
37         bool stopped;
38         bool empty;
39
40         /* called when the runqueue is emptied */
41         void (*empty_cb)(struct runqueue *q);
42 };
43
44 struct runqueue_task_type {
45         const char *name;
46
47         /*
48          * called when a task is requested to run
49          *
50          * The task is removed from the list before this callback is run. It
51          * can re-arm itself using runqueue_task_add.
52          */
53         void (*run)(struct runqueue *q, struct runqueue_task *t);
54
55         /*
56          * called to request cancelling a task
57          *
58          * int type is used as an optional hint for the method to be used when
59          * cancelling the task, e.g. a signal number for processes. Calls
60          * runqueue_task_complete when done.
61          */
62         void (*cancel)(struct runqueue *q, struct runqueue_task *t, int type);
63
64         /*
65          * called to kill a task. must not make any calls to runqueue_task_complete,
66          * it has already been removed from the list.
67          */
68         void (*kill)(struct runqueue *q, struct runqueue_task *t);
69 };
70
71 struct runqueue_task {
72         struct safe_list list;
73         const struct runqueue_task_type *type;
74         struct runqueue *q;
75
76         void (*complete)(struct runqueue *q, struct runqueue_task *t);
77
78         struct uloop_timeout timeout;
79         int run_timeout;
80         int cancel_timeout;
81         int cancel_type;
82
83         bool queued;
84         bool running;
85         bool cancelled;
86 };
87
88 struct runqueue_process {
89         struct runqueue_task task;
90         struct uloop_process proc;
91 };
92
93 void runqueue_init(struct runqueue *q);
94 void runqueue_cancel(struct runqueue *q);
95 void runqueue_cancel_active(struct runqueue *q);
96 void runqueue_cancel_pending(struct runqueue *q);
97 void runqueue_kill(struct runqueue *q);
98
99 void runqueue_stop(struct runqueue *q);
100 void runqueue_resume(struct runqueue *q);
101
102 void runqueue_task_add(struct runqueue *q, struct runqueue_task *t, bool running);
103 void runqueue_task_add_first(struct runqueue *q, struct runqueue_task *t, bool running);
104 void runqueue_task_complete(struct runqueue_task *t);
105
106 void runqueue_task_cancel(struct runqueue_task *t, int type);
107 void runqueue_task_kill(struct runqueue_task *t);
108
109 void runqueue_process_add(struct runqueue *q, struct runqueue_process *p, pid_t pid);
110
111 /* to be used only from runqueue_process callbacks */
112 void runqueue_process_cancel_cb(struct runqueue *q, struct runqueue_task *t, int type);
113 void runqueue_process_kill_cb(struct runqueue *q, struct runqueue_task *t);
114
115 #endif