+ SILC_LOG_DEBUG(("In scheduler loop"));
+
+ /* 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;
+ }
+
+ /* Clear everything */
+ FD_ZERO(&schedule.in);
+ FD_ZERO(&schedule.out);
+ schedule.max_fd = -1;
+ is_run = FALSE;
+
+ /* Calculate next timeout for select(). This is the timeout value
+ when at earliest some of the timeout tasks expire. */
+ SILC_SCHEDULE_SELECT_TIMEOUT;
+
+ /* 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 (schedule.max_fd == -1) {
+ /*SILC_LOG_ERROR(("Nothing to listen, exiting"));*/
+ return FALSE;
+ }
+
+ 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"));
+ if (timeout_usecs < 0)
+ memcpy(&timeout, schedule.timeout, sizeof(timeout));
+ else {
+ timeout.tv_sec = 0;
+ timeout.tv_usec = timeout_usecs;
+ }
+ switch (select(schedule.max_fd + 1, &schedule.in,
+ &schedule.out, 0, &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_SCHEDULE_RUN_GENERIC_TASKS;
+ break;
+ }
+ return TRUE;
+}
+
+/* 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()
+{