-/* Executes tasks matching the file descriptor set by select(). The task
- remains on the task queue after execution. Invalid tasks are removed
- here from the task queue. This macro is used by silc_schedule function.
- We don't have to care about the tasks priority here because the tasks
- are sorted in their priority order already at the registration phase. */
-
-#define SILC_SCHEDULE_RUN_TASKS \
-do { \
- queue = schedule->fd_queue; \
- if (queue && queue->valid == TRUE && queue->task) { \
- task = queue->task; \
- \
- /* Walk thorugh all tasks in the particular task queue and \
- execute the callback functions of those tasks matching the \
- fd set by select(). */ \
- while(1) { \
- /* Validity of the task is checked always before and after \
- execution beacuse the task might have been unregistered \
- in the callback function, ie. it is not valid anymore. */ \
- \
- if (task->valid) { \
- /* Task ready for reading */ \
- if ((FD_ISSET(task->fd, &schedule->in)) && \
- (task->iomask & (1L << SILC_TASK_READ))) { \
- task->callback(queue, SILC_TASK_READ, task->context, task->fd); \
- is_run = TRUE; \
- } \
- } \
- \
- if (task->valid) { \
- /* Task ready for writing */ \
- if ((FD_ISSET(task->fd, &schedule->out)) && \
- (task->iomask & (1L << SILC_TASK_WRITE))) { \
- task->callback(queue, SILC_TASK_WRITE, task->context, task->fd); \
- is_run = TRUE; \
- } \
- } \
- \
- if (!task->valid) { \
- /* Invalid (unregistered) tasks are removed from the \
- task queue. */ \
- if (queue->task == task->next) { \
- silc_task_remove(queue, task); \
- break; \
- } \
- \
- task = task->next; \
- silc_task_remove(queue, task->prev); \
- continue; \
- } \
- \
- /* Break if there isn't more tasks in the queue */ \
- if (queue->task == task->next) \
- break; \
- \
- task = task->next; \
- } \
- } \
-} while(0)
-
-/* Selects tasks to be listened by select(). These are the non-timeout
- tasks. This checks the scheduler's fd list. This macro is used by
- silc_schedule function. */
-
-#define SILC_SCHEDULE_SELECT_TASKS \
-do { \
- for (i = 0; i <= schedule->fd_list.last_fd; i++) { \
- if (schedule->fd_list.fd[i] != -1) { \
- \
- /* Set the max fd value for select() to listen */ \
- if (i > schedule->max_fd) \
- schedule->max_fd = i; \
- \
- /* Add tasks for reading */ \
- if ((schedule->fd_list.fd[i] & (1L << SILC_TASK_READ))) \
- FD_SET(i, &schedule->in); \
- \
- /* Add tasks for writing */ \
- if ((schedule->fd_list.fd[i] & (1L << SILC_TASK_WRITE))) \
- FD_SET(i, &schedule->out); \
- } \
- } \
-} while(0)
-
-/* Executes all tasks whose timeout has expired. The task is removed from
- the task queue after the callback function has returned. Also, invalid
- tasks are removed here. The current time must be get before calling this
- macro. This macro is used by silc_schedule function. We don't have to
- care about priorities because tasks are already sorted in their priority
- order at the registration phase. */
-
-#define SILC_SCHEDULE_RUN_TIMEOUT_TASKS \
-do { \
- queue = schedule->timeout_queue; \
- if (queue && queue->valid == TRUE && queue->task) { \
- task = queue->task; \
- \
- /* Walk thorugh all tasks in the particular task queue \
- and run all the expired tasks. */ \
- while(1) { \
- /* Execute the task if the timeout has expired */ \
- if (silc_task_timeout_compare(&task->timeout, &curtime)) { \
- \
- /* Task ready for reading */ \
- if (task->valid) { \
- if ((task->iomask & (1L << SILC_TASK_READ))) \
- task->callback(queue, SILC_TASK_READ, \
- task->context, task->fd); \
- } \
- \
- /* Task ready for writing */ \
- if (task->valid) { \
- if ((task->iomask & (1L << SILC_TASK_WRITE))) \
- task->callback(queue, SILC_TASK_WRITE, \
- task->context, task->fd); \
- } \
- \
- /* Break if there isn't more tasks in the queue */ \
- if (queue->task == task->next) { \
- /* Remove the task from queue */ \
- silc_task_remove(queue, task); \
- break; \
- } \
- \
- task = task->next; \
- \
- /* Remove the task from queue */ \
- silc_task_remove(queue, task->prev); \
- } else { \
- /* The timeout hasn't expired, check for next one */ \
- \
- /* Break if there isn't more tasks in the queue */ \
- if (queue->task == task->next) \
- break; \
- \
- task = task->next; \
- } \
- } \
- } \
-} while(0)
-
-/* Calculates next timeout for select(). This is the timeout value
- when at earliest some of the timeout tasks expire. If this is in the
- past, they will be run now. This macro is used by the silc_schedule
- function. */
-
-#define SILC_SCHEDULE_SELECT_TIMEOUT \
-do { \
- if (schedule->timeout_queue && schedule->timeout_queue->valid == TRUE) { \
- queue = schedule->timeout_queue; \
- task = NULL; \
- \
- /* Get the current time */ \
- gettimeofday(&curtime, NULL); \
- schedule->timeout = NULL; \
- \
- /* First task in the task queue has always the smallest timeout. */ \
- task = queue->task; \
- while(1) { \
- if (task && task->valid == TRUE) { \
- \
- /* If the timeout is in past, we will run the task and all other \
- timeout tasks from the past. */ \
- if (silc_task_timeout_compare(&task->timeout, &curtime)) { \
- SILC_SCHEDULE_RUN_TIMEOUT_TASKS; \
- \
- /* The task(s) has expired and doesn't exist on the task queue \
- anymore. We continue with new timeout. */ \
- queue = schedule->timeout_queue; \
- task = queue->task; \
- if (task == NULL || task->valid == FALSE) \
- break; \
- goto cont; \
- } else { \
- cont: \
- /* Calculate the next timeout for select() */ \
- queue->timeout.tv_sec = task->timeout.tv_sec - curtime.tv_sec; \
- queue->timeout.tv_usec = task->timeout.tv_usec - curtime.tv_usec; \
- if (queue->timeout.tv_sec < 0) \
- queue->timeout.tv_sec = 0; \
- \
- /* We wouldn't want to go under zero, check for it. */ \
- if (queue->timeout.tv_usec < 0) { \
- queue->timeout.tv_sec -= 1; \
- if (queue->timeout.tv_sec < 0) \
- queue->timeout.tv_sec = 0; \
- queue->timeout.tv_usec += 1000000L; \
- } \
- } \
- /* We've got the timeout value */ \
- break; \
- } else { \
- /* Task is not valid, remove it and try next one. */ \
- silc_task_remove(queue, task); \
- task = queue->task; \
- if (queue->task == NULL) \
- break; \
- } \
- } \
- /* Save the timeout */ \
- if (task) \
- schedule->timeout = &queue->timeout; \
- } \
-} while(0)
-
-/* Execute generic tasks. These are executed only and only if for the
- specific fd there wasn't other non-timeout tasks. This checks the earlier
- set fd list, thus the generic tasks apply to all specified fd's. All the
- generic tasks are executed at once. */
-
-#define SILC_SCHEDULE_RUN_GENERIC_TASKS \
-do { \
- if (is_run == FALSE) { \
- SILC_LOG_DEBUG(("Running generic tasks")); \
- for (i = 0; i <= schedule->fd_list.last_fd; i++) \
- if (schedule->fd_list.fd[i] != -1) { \
- \
- /* Check whether this fd is select()ed. */ \
- if ((FD_ISSET(i, &schedule->in)) || (FD_ISSET(i, &schedule->out))) { \
- \
- /* It was selected. Now find the tasks from task queue and execute \
- all generic tasks. */ \
- if (schedule->generic_queue && schedule->generic_queue->valid) { \
- queue = schedule->generic_queue; \
- \
- if (!queue->task) \
- break; \
- \
- task = queue->task; \
- \
- while(1) { \
- /* Validity of the task is checked always before and after \
- execution beacuse the task might have been unregistered \
- in the callback function, ie. it is not valid anymore. */ \
- \
- if (task->valid && schedule->fd_list.fd[i] != -1) { \
- /* Task ready for reading */ \
- if ((schedule->fd_list.fd[i] & (1L << SILC_TASK_READ))) \
- task->callback(queue, SILC_TASK_READ, \
- task->context, i); \
- } \
- \
- if (task->valid && schedule->fd_list.fd[i] != -1) { \
- /* Task ready for writing */ \
- if ((schedule->fd_list.fd[i] & (1L << SILC_TASK_WRITE))) \
- task->callback(queue, SILC_TASK_WRITE, \
- task->context, i); \
- } \
- \
- if (!task->valid) { \
- /* Invalid (unregistered) tasks are removed from the \
- task queue. */ \
- if (queue->task == task->next) { \
- silc_task_remove(queue, task); \
- break; \
- } \
- \
- task = task->next; \
- silc_task_remove(queue, task->prev); \
- continue; \
- } \
- \
- /* Break if there isn't more tasks in the queue */ \
- if (queue->task == task->next) \
- break; \
- \
- task = task->next; \
- } \
- } \
- } \
- } \
- } \
-} while(0)
-
-bool silc_schedule_one(SilcSchedule schedule, int timeout_usecs)