2 * runqueue.c - a simple task queueing/completion tracking helper
4 * Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
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.
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.
19 #ifndef __LIBUBOX_RUNQUEUE_H
20 #define __LIBUBOX_RUNQUEUE_H
23 #include "safe_list.h"
28 struct runqueue_task_type;
31 struct safe_list tasks_active;
32 struct safe_list tasks_inactive;
33 struct uloop_timeout timeout;
36 int max_running_tasks;
40 /* called when the runqueue is emptied */
41 void (*empty_cb)(struct runqueue *q);
44 struct runqueue_task_type {
48 * called when a task is requested to run
50 * The task is removed from the list before this callback is run. It
51 * can re-arm itself using runqueue_task_add.
53 void (*run)(struct runqueue *q, struct runqueue_task *t);
56 * called to request cancelling a task
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.
62 void (*cancel)(struct runqueue *q, struct runqueue_task *t, int type);
65 * called to kill a task. must not make any calls to runqueue_task_complete,
66 * it has already been removed from the list.
68 void (*kill)(struct runqueue *q, struct runqueue_task *t);
71 struct runqueue_task {
72 struct safe_list list;
73 const struct runqueue_task_type *type;
76 void (*complete)(struct runqueue *q, struct runqueue_task *t);
78 struct uloop_timeout timeout;
88 struct runqueue_process {
89 struct runqueue_task task;
90 struct uloop_process proc;
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 \
99 #define RUNQUEUE(_name, _max_running) \
100 struct runqueue _name = RUNQUEUE_INIT(_name, _max_running)
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);
108 void runqueue_stop(struct runqueue *q);
109 void runqueue_resume(struct runqueue *q);
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);
115 void runqueue_task_cancel(struct runqueue_task *t, int type);
116 void runqueue_task_kill(struct runqueue_task *t);
118 void runqueue_process_add(struct runqueue *q, struct runqueue_process *p, pid_t pid);
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);