blobmsg: introduce BLOBMSG_CAST_INT64
[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. The cancel
60 * callback should call 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 * which will be called after this returns.
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 #define RUNQUEUE_INIT(_name, _max_running) { \
94 .tasks_active = SAFE_LIST_INIT(_name.tasks_active), \
95 .tasks_inactive = SAFE_LIST_INIT(_name.tasks_inactive), \
96 .max_running_tasks = _max_running \
97 }
98
99 #define RUNQUEUE(_name, _max_running) \
100 struct runqueue _name = RUNQUEUE_INIT(_name, _max_running)
101
102 void runqueue_init(struct runqueue *q);
103 void runqueue_cancel(struct runqueue *q);
104 void runqueue_cancel_active(struct runqueue *q);
105 void runqueue_cancel_pending(struct runqueue *q);
106 void runqueue_kill(struct runqueue *q);
107
108 void runqueue_stop(struct runqueue *q);
109 void runqueue_resume(struct runqueue *q);
110
111 void runqueue_task_add(struct runqueue *q, struct runqueue_task *t, bool running);
112 void runqueue_task_add_first(struct runqueue *q, struct runqueue_task *t, bool running);
113 void runqueue_task_complete(struct runqueue_task *t);
114
115 void runqueue_task_cancel(struct runqueue_task *t, int type);
116 void runqueue_task_kill(struct runqueue_task *t);
117
118 void runqueue_process_add(struct runqueue *q, struct runqueue_process *p, pid_t pid);
119
120 /* to be used only from runqueue_process callbacks */
121 void runqueue_process_cancel_cb(struct runqueue *q, struct runqueue_task *t, int type);
122 void runqueue_process_kill_cb(struct runqueue *q, struct runqueue_task *t);
123
124 #endif