1 /****h* silcutil/silcschedule.h
9 * Author: Pekka Riikonen <priikone@silcnet.org>
11 * Copyright (C) 1998 - 2001 Pekka Riikonen
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
25 * The SILC Scheduler is the heart of any application. The scheduler provides
26 * the application's main loop that can handle incoming data, outgoing data,
27 * timeouts and dispatch different kind of tasks.
29 * The SILC Scheduler supports file descriptor based tasks, timeout tasks
30 * and generic tasks. File descriptor tasks are tasks that perform some
31 * operation over the specified file descriptor. These include network
32 * connections, for example. The timeout tasks are timeouts that are executed
33 * after the specified timeout has elapsed. The generic tasks are tasks that
34 * apply to all registered file descriptors thus providing one task that
35 * applies to many independent connections.
37 * The SILC Scheduler is designed to be the sole main loop of the application
38 * so that the application does not need any other main loop. However,
39 * SILC Scheduler does support running the scheduler only once, so that the
40 * scheduler does not block, and thus providing a possiblity that some
41 * external main loop is run over the SILC Scheduler. However, these
42 * applications are considered to be special cases.
44 * Typical application first initializes the scheduler and then registers
45 * the very first tasks to the scheduler and then run the scheduler. After
46 * the scheduler's run function returns the application is considered to be
49 * The SILC Scheduler supports multi-threads as well. The actual scheduler
50 * must be run in single-thread but other threads may register new tasks
51 * and unregister old tasks. However, it is enforced that the actual
52 * task is always run in the main thread. The scheduler is context based
53 * which makes it possible to allocate several schedulers for one application.
54 * Since the scheduler must be run in single-thread, a multi-threaded
55 * application could be created by allocating own scheduler for each of the
56 * worker threads. However, in this case the schedulers must not share
57 * same task queues. Each of the schedulers must allocate their own
60 * See the SILC Task API for task management interface. It is used to
61 * register and unregister the actual tasks.
65 #ifndef SILCSCHEDULE_H
66 #define SILCSCHEDULE_H
68 /****s* silcutil/SilcScheduleAPI/SilcSchedule
72 * typedef struct SilcScheduleStruct *SilcSchedule;
76 * This context is the actual Scheduler and is allocated by
77 * the silc_schedule_init funtion. The context is given as argument
78 * to all silc_schedule_* functions. It must be freed by the
79 * silc_schedule_uninit function.
82 typedef struct SilcScheduleStruct *SilcSchedule;
86 /****f* silcutil/SilcScheduleAPI/silc_schedule_init
90 * SilcSchedule silc_schedule_init(SilcTaskQueue *fd_queue,
91 * SilcTaskQueue *timeout_queue,
92 * SilcTaskQueue *generic_queue,
97 * Initializes the scheduler. Sets the non-timeout task queue hook,
98 * the timeout task queue hook, and the generic task queue hook. This
99 * must be called before the scheduler is able to work. This will
100 * allocate the queue pointers if they are not allocated. Returns the
101 * scheduler context that must be freed by the silc_schedule_uninit
105 SilcSchedule silc_schedule_init(SilcTaskQueue *fd_queue,
106 SilcTaskQueue *timeout_queue,
107 SilcTaskQueue *generic_queue,
110 /****f* silcutil/SilcScheduleAPI/silc_schedule_uninit
114 * bool silc_schedule_uninit(SilcSchedule schedule);
118 * Uninitializes the schedule. This is called when the program is ready
119 * to end. This removes all tasks and task queues. Returns FALSE if the
120 * scheduler could not be uninitialized. This happens when the scheduler
121 * is still valid and silc_schedule_stop has not been called.
124 bool silc_schedule_uninit(SilcSchedule schedule);
126 /****f* silcutil/SilcScheduleAPI/silc_schedule_stop
130 * void silc_schedule_stop(SilcSchedule schedule);
134 * Stops the scheduler even if it is not supposed to be stopped yet.
135 * After calling this, one must call silc_schedule_uninit (after the
136 * silc_schedule has returned).
139 void silc_schedule_stop(SilcSchedule schedule);
141 /****f* silcutil/SilcScheduleAPI/silc_schedule_set_listen_fd
145 * void silc_schedule_set_listen_fd(SilcSchedule schedule,
146 * int fd, uint32 iomask);
150 * Sets a file descriptor to be listened by the scheduler. One can
151 * call this directly if wanted. This can be called multiple times for
152 * one file descriptor to set different iomasks.
155 void silc_schedule_set_listen_fd(SilcSchedule schedule, int fd, uint32 iomask);
157 /****f* silcutil/SilcScheduleAPI/silc_schedule_unset_listen_fd
161 * void silc_schedule_unset_listen_fd(SilcSchedule schedule, int fd);
165 * Removes a file descriptor from listen list. The file descriptor
166 * is not listened by the scheduler after this function.
169 void silc_schedule_unset_listen_fd(SilcSchedule schedule, int fd);
171 /****f* silcutil/SilcScheduleAPI/silc_schedule
175 * void silc_schedule(SilcSchedule schedule);
179 * The SILC scheduler. This is actually the main routine in SILC programs.
180 * When this returns the program is to be ended. Before this function can
181 * be called, one must call silc_schedule_init function.
184 void silc_schedule(SilcSchedule schedule);
186 /****f* silcutil/SilcScheduleAPI/silc_schedule
190 * bool silc_schedule_one(SilcSchedule schedule, int block);
194 * Same as the silc_schedule but runs the scheduler only one round
195 * and then returns. This function is handy when the SILC scheduler
196 * is used inside some other external scheduler, for example. If
197 * the `timeout_usecs' is non-negative a timeout will be added to the
198 * scheduler. The function will not return in this timeout unless
199 * some other event occurs.
202 bool silc_schedule_one(SilcSchedule schedule, int timeout_usecs);
204 /****f* silcutil/SilcScheduleAPI/silc_schedule_wakeup
208 * void silc_schedule_wakeup(SilcSchedule schedule);
212 * Wakes up the scheduler. This is used only in multi-threaded
213 * environments where threads may add new tasks or remove old tasks
214 * from task queues. This is called to wake up the scheduler in the
215 * main thread so that it detects the changes in the task queues.
216 * If threads support is not compiled in this function has no effect.
217 * Implementation of this function may be platform specific.
220 void silc_schedule_wakeup(SilcSchedule schedule);