/* Internal task management routines. */
+static void silc_schedule_dispatch_timeout(SilcSchedule schedule,
+ bool dispatch_all);
static void silc_task_queue_alloc(SilcTaskQueue *queue);
static void silc_task_queue_free(SilcTaskQueue queue);
static SilcTask silc_task_find(SilcTaskQueue queue, SilcUInt32 fd);
if (schedule->valid == TRUE)
return FALSE;
+ /* Dispatch all timeouts before going away */
+ silc_mutex_lock(schedule->timeout_queue->lock);
+ silc_schedule_dispatch_timeout(schedule, TRUE);
+ silc_mutex_unlock(schedule->timeout_queue->lock);
+
+ /* Deliver signals before going away */
+ if (schedule->signal_tasks) {
+ SILC_SCHEDULE_UNLOCK(schedule);
+ silc_schedule_internal_signals_call(schedule->internal, schedule);
+ schedule->signal_tasks = FALSE;
+ SILC_SCHEDULE_LOCK(schedule);
+ }
+
/* Unregister all tasks */
silc_schedule_task_remove(schedule->fd_queue, SILC_ALL_TASKS);
silc_schedule_task_remove(schedule->timeout_queue, SILC_ALL_TASKS);
phase. */
/* This holds the schedule->lock and the schedule->timeout_queue->lock */
-static void silc_schedule_dispatch_timeout(SilcSchedule schedule)
+static void silc_schedule_dispatch_timeout(SilcSchedule schedule,
+ bool dispatch_all)
{
SilcTaskQueue queue = schedule->timeout_queue;
SilcTask task;
the expired tasks. */
while(1) {
/* Execute the task if the timeout has expired */
- if (silc_schedule_task_timeout_compare(&task->timeout, &curtime)) {
+ if (dispatch_all ||
+ silc_schedule_task_timeout_compare(&task->timeout, &curtime)) {
if (task->valid) {
silc_mutex_unlock(queue->lock);
SILC_SCHEDULE_UNLOCK(schedule);
/* If the timeout is in past, we will run the task and all other
timeout tasks from the past. */
if (silc_schedule_task_timeout_compare(&task->timeout, &curtime)) {
- silc_schedule_dispatch_timeout(schedule);
-
+ silc_schedule_dispatch_timeout(schedule, FALSE);
+
/* The task(s) has expired and doesn't exist on the task queue
anymore. We continue with new timeout. */
queue = schedule->timeout_queue;
case 0:
/* Timeout */
silc_mutex_lock(schedule->timeout_queue->lock);
- silc_schedule_dispatch_timeout(schedule);
+ silc_schedule_dispatch_timeout(schedule, FALSE);
silc_mutex_unlock(schedule->timeout_queue->lock);
break;
default:
SilcTaskQueue queue;
int timeout = FALSE;
+ if (!schedule->valid)
+ return NULL;
+
SILC_LOG_DEBUG(("Registering new task, fd=%d type=%d priority=%d", fd,
type, priority));
int i;
bool found = FALSE;
+ if (!schedule->valid)
+ return;
+
SILC_SCHEDULE_LOCK(schedule);
for (i = 0; i < schedule->max_fd; i++)