summaryrefslogtreecommitdiff
path: root/sched.h
blob: e207b4aa1adbc86748c7fa70334bcbd574c1dad0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/* SPDX-License-Identifier: GPL-2.0 */

/** \file sched.h The paraslash scheduler
 *
 * Most paraslash executables employ the scheduler to perform non-blocking I/O
 * to more than one file descriptor without threading.
 *
 * The scheduler maintains a list of task structures where each list element
 * represents a task that has been registered to the scheduler by calling \ref
 * task_register(). At each iteration of main loop, the scheduler first calls
 * the \ref task_info::pre_monitor() method of each registered task to set
 * up two file descriptor sets and to compute the timeout for the subsequent
 * call to poll(2). The \ref task_info::post_monitor() method of each task is
 * called after poll(2) returns. These methods perform read/write operations
 * if the poll(2) call indicated that their file descriptors are ready for I/O.
 *
 * Inter-task communication is possible through a notification API also
 * described here.
 *
 * The functions declared here are implemented in \ref sched.c.
 */

struct sched;

/**
 * Information that must be supplied by callers of \ref task_register().
 *
 * The structure may be safely discarded after the task has been registered.
 */
struct task_info {
	/** Used for log messages and by \ref get_task_list(). */
	const char *name;
	/**
	 * Configure watch fds and impose an upper bound on the I/O timeout.
	 *
	 * If this is not NULL, the function is called at each iteration of the
	 * scheduler's main loop. Its purpose is to tell the scheduler that
	 * certain file descriptors should be monitored for readiness for I/O.
	 * The function may also lower the scheduler's timeout value (but shall
	 * never increase it) to impose an upper bound on the waiting time in
	 * case no file descriptors happen to be ready.
	 *
	 * \sa \ref time.c.
	 */
	void (*pre_monitor)(struct sched *s, void *context);
	/**
	 * Perform I/O on file descriptors which are ready for I/O.
	 *
	 * This mandatory hook is called after the system call which monitors
	 * file descriptors returns. The function should perform non-blocking
	 * I/O on those file descriptors which are reported as being ready.
	 *
	 * If this function returns a negative value, the scheduler unregisters
	 * the task.
	 */
	int (*post_monitor)(struct sched *s, void *context);
	/**
	 * This pointer is saved when the task is registered. It is passed to
	 * ->pre_monitor() and ->post_monitor(). Usually this is a pointer to the
	 * struct owned by the caller which contains the task pointer.
	 */
	void *context;
};

/**
 * This is set by the scheduler at the beginning of its main loop.  It may be
 * used (read-only) from everywhere. As none of the functions called by the
 * scheduler are allowed to block, this value should be accurate enough so that
 * there is no need to call clock_gettime() directly.
 */
extern const struct timeval *now;

struct sched *sched_new(int (*poll_function)(struct pollfd *, nfds_t, int));
struct task *task_register(struct task_info *info, struct sched *s);
int schedule(struct sched *s);
void sched_shutdown(struct sched *s);
char *get_task_list(struct sched *s);
void task_notify(struct task *t, int err);
void task_notify_all(struct sched *s, int err);
int task_get_notification(const struct task *t);
int task_status(const struct task *t);
int task_reap(struct task **tptr);
void sched_min_delay(struct sched *s);
void sched_request_timeout(struct timeval *to, struct sched *s);
void sched_request_timeout_ms(long unsigned ms, struct sched *s);
int sched_request_barrier(struct timeval *barrier, struct sched *s);
int sched_request_barrier_or_min_delay(struct timeval *barrier, struct sched *s);
void sched_monitor_readfd(int fd, struct sched *s);
void sched_monitor_writefd(int fd, struct sched *s);
bool sched_read_ok(int fd, const struct sched *s);
bool sched_write_ok(int fd, const struct sched *s);