GNU General Public License for more details.
*/
-/*
- * $Id$
- * $Log$
- * Revision 1.1 2000/09/13 17:45:16 priikone
- * Splitted SILC core library. Core library includes now only
- * SILC protocol specific stuff. New utility library includes the
- * old stuff from core library that is more generic purpose stuff.
- *
- * Revision 1.3 2000/07/18 06:51:58 priikone
- * Debug version bug fixes.
- *
- * Revision 1.2 2000/07/05 06:06:35 priikone
- * Global cosmetic change.
- *
- * Revision 1.1.1.1 2000/06/27 11:36:55 priikone
- * Imported from internal CVS/Added Log headers.
- *
- *
- */
+/* $Id$ */
#include "silcincludes.h"
call this directly if wanted. This can be called multiple times for
one file descriptor to set different iomasks. */
-void silc_schedule_set_listen_fd(int fd, unsigned int iomask)
+void silc_schedule_set_listen_fd(int fd, uint32 iomask)
{
assert(schedule.valid != FALSE);
assert(fd < schedule.fd_list.max_fd);
if (schedule.fd_list.fd[i] != -1)
break;
- schedule.fd_list.last_fd = i;
+ schedule.fd_list.last_fd = i < 0 ? 0 : i;
}
}
} \
} while(0)
-/* The SILC scheduler. This is actually the main routine in SILC programs.
- When this returns the program is to be ended. Before this function can
- be called, one must call silc_schedule_init function. */
-
-void silc_schedule()
+int silc_schedule_one(int timeout_usecs)
{
+ struct timeval timeout;
int is_run, i;
SilcTask task;
SilcTaskQueue queue;
struct timeval curtime;
- SILC_LOG_DEBUG(("Running scheduler"));
+ SILC_LOG_DEBUG(("In scheduler loop"));
- if (schedule.valid == FALSE) {
- SILC_LOG_ERROR(("Scheduler is not valid, stopping"));
- return;
+ /* If the task queues aren't initialized or we aren't valid anymore
+ we will return */
+ if ((!schedule.fd_queue && !schedule.timeout_queue
+ && !schedule.generic_queue) || schedule.valid == FALSE) {
+ SILC_LOG_DEBUG(("Scheduler not valid anymore, exiting"));
+ return FALSE;
}
- /* Start the scheduler loop */
- while(1) {
+ /* Clear everything */
+ FD_ZERO(&schedule.in);
+ FD_ZERO(&schedule.out);
+ schedule.max_fd = -1;
+ is_run = FALSE;
- SILC_LOG_DEBUG(("In scheduler loop"));
+ /* Calculate next timeout for select(). This is the timeout value
+ when at earliest some of the timeout tasks expire. */
+ SILC_SCHEDULE_SELECT_TIMEOUT;
- /* If the task queues aren't initialized or we aren't valid anymore
- we will return */
- if ((!schedule.fd_queue && !schedule.timeout_queue
- && !schedule.generic_queue) || schedule.valid == FALSE) {
- SILC_LOG_DEBUG(("Scheduler not valid anymore, exiting"));
- break;
- }
+ /* Add the file descriptors to the fd sets. These are the non-timeout
+ tasks. The select() listens to these file descriptors. */
+ SILC_SCHEDULE_SELECT_TASKS;
- /* Clear everything */
- FD_ZERO(&schedule.in);
- FD_ZERO(&schedule.out);
- schedule.max_fd = -1;
- is_run = FALSE;
+ if (schedule.max_fd == -1 && !schedule.timeout)
+ return FALSE;
- /* Calculate next timeout for select(). This is the timeout value
- when at earliest some of the timeout tasks expire. */
- SILC_SCHEDULE_SELECT_TIMEOUT;
+ if (schedule.timeout) {
+ SILC_LOG_DEBUG(("timeout: sec=%d, usec=%d", schedule.timeout->tv_sec,
+ schedule.timeout->tv_usec));
+ }
- /* Add the file descriptors to the fd sets. These are the non-timeout
- tasks. The select() listens to these file descriptors. */
- SILC_SCHEDULE_SELECT_TASKS;
+ if (timeout_usecs >= 0) {
+ timeout.tv_sec = 0;
+ timeout.tv_usec = timeout_usecs;
+ schedule.timeout = &timeout;
+ }
- if (schedule.max_fd == -1) {
- SILC_LOG_ERROR(("Nothing to listen, exiting"));
+ /* This is the main select(). The program blocks here until some
+ of the selected file descriptors change status or the selected
+ timeout expires. */
+ SILC_LOG_DEBUG(("Select"));
+ switch (select(schedule.max_fd + 1, &schedule.in,
+ &schedule.out, 0, schedule.timeout)) {
+ case -1:
+ /* Error */
+ if (errno == EINTR)
break;
- }
-
- if (schedule.timeout) {
- SILC_LOG_DEBUG(("timeout: sec=%d, usec=%d", schedule.timeout->tv_sec,
- schedule.timeout->tv_usec));
- }
-
- /* This is the main select(). The program blocks here until some
- of the selected file descriptors change status or the selected
- timeout expires. */
- SILC_LOG_DEBUG(("Select"));
- switch(select(schedule.max_fd + 1, &schedule.in,
- &schedule.out, 0, schedule.timeout)) {
- case -1:
- /* Error */
- SILC_LOG_ERROR(("Error in select(): %s", strerror(errno)));
- break;
- case 0:
- /* Timeout */
- SILC_LOG_DEBUG(("Running timeout tasks"));
- gettimeofday(&curtime, NULL);
- SILC_SCHEDULE_RUN_TIMEOUT_TASKS;
- break;
- default:
- /* There is some data available now */
- SILC_LOG_DEBUG(("Running non-timeout tasks"));
- SILC_SCHEDULE_RUN_TASKS;
+ SILC_LOG_ERROR(("Error in select(): %s", strerror(errno)));
+ break;
+ case 0:
+ /* Timeout */
+ SILC_LOG_DEBUG(("Running timeout tasks"));
+ gettimeofday(&curtime, NULL);
+ SILC_SCHEDULE_RUN_TIMEOUT_TASKS;
+ break;
+ default:
+ /* There is some data available now */
+ SILC_LOG_DEBUG(("Running non-timeout tasks"));
+ SILC_SCHEDULE_RUN_TASKS;
+
+ SILC_SCHEDULE_RUN_GENERIC_TASKS;
+ break;
+ }
+ return TRUE;
+}
- SILC_SCHEDULE_RUN_GENERIC_TASKS;
- break;
- }
+/* The SILC scheduler. This is actually the main routine in SILC programs.
+ When this returns the program is to be ended. Before this function can
+ be called, one must call silc_schedule_init function. */
+
+void silc_schedule()
+{
+ SILC_LOG_DEBUG(("Running scheduler"));
+
+ if (schedule.valid == FALSE) {
+ SILC_LOG_ERROR(("Scheduler is not valid, stopping"));
+ return;
}
+
+ /* Start the scheduler loop */
+ while (silc_schedule_one(-1))
+ ;
}