/* Set the pointers */
(*new)->schedule = schedule;
(*new)->valid = valid;
+ silc_mutex_alloc(&(*new)->lock);
}
/* Free's a task queue. */
void silc_task_queue_free(SilcTaskQueue queue)
{
+ silc_mutex_lock(queue->lock);
+ queue->valid = FALSE;
+ silc_mutex_unlock(queue->lock);
+ silc_mutex_free(queue->lock);
silc_free(queue);
}
/* If the task is generic task, we check whether this task has already
been registered. Generic tasks are registered only once and after that
the same task applies to all file descriptors to be registered. */
- if ((type == SILC_TASK_GENERIC) && queue->task) {
- SilcTask task;
-
- task = queue->task;
- while(1) {
- if ((task->callback == cb) && (task->context == context)) {
- SILC_LOG_DEBUG(("Found matching generic task, using the match"));
-
- /* Add the fd to be listened, the task found now applies to this
- fd as well. */
- silc_schedule_set_listen_fd(queue->schedule,
- fd, (1L << SILC_TASK_READ));
- return task;
+ if (type == SILC_TASK_GENERIC) {
+ silc_mutex_lock(queue->lock);
+
+ if (queue->task) {
+ SilcTask task = queue->task;
+ while(1) {
+ if ((task->callback == cb) && (task->context == context)) {
+ SILC_LOG_DEBUG(("Found matching generic task, using the match"));
+
+ silc_mutex_unlock(queue->lock);
+
+ /* Add the fd to be listened, the task found now applies to this
+ fd as well. */
+ silc_schedule_set_listen_fd(queue->schedule,
+ fd, (1L << SILC_TASK_READ));
+ return task;
+ }
+
+ if (queue->task == task->next)
+ break;
+
+ task = task->next;
}
-
- if (queue->task == task->next)
- break;
-
- task = task->next;
}
+
+ silc_mutex_unlock(queue->lock);
}
new = silc_calloc(1, sizeof(*new));
new->next = new;
new->prev = new;
- /* If the task is non-timeout task we have to tell the scheduler that we
- would like to have these tasks scheduled at some odd distant future. */
- if (type != SILC_TASK_TIMEOUT)
- silc_schedule_set_listen_fd(queue->schedule, fd, (1L << SILC_TASK_READ));
-
/* Create timeout if marked to be timeout task */
if (((seconds + useconds) > 0) && (type == SILC_TASK_TIMEOUT)) {
silc_gettimeofday(&new->timeout);
timeout = TRUE;
}
+ /* If the task is non-timeout task we have to tell the scheduler that we
+ would like to have these tasks scheduled at some odd distant future. */
+ if (type != SILC_TASK_TIMEOUT)
+ silc_schedule_set_listen_fd(queue->schedule, fd, (1L << SILC_TASK_READ));
+
+ silc_mutex_lock(queue->lock);
+
/* Is this first task of the queue? */
if (queue->task == NULL) {
queue->task = new;
+ silc_mutex_unlock(queue->lock);
return new;
}
if (timeout)
- return silc_task_add_timeout(queue, new, priority);
+ new = silc_task_add_timeout(queue, new, priority);
else
- return silc_task_add(queue, new, priority);
+ new = silc_task_add(queue, new, priority);
+
+ silc_mutex_unlock(queue->lock);
+
+ return new;
}
/* Removes (unregisters) a task from particular task queue. This function
{
SilcTask first, old, next;
- if (!queue || !queue->task)
+ if (!queue)
+ return FALSE;
+
+ silc_mutex_lock(queue->lock);
+
+ if (!queue->task) {
+ silc_mutex_unlock(queue->lock);
return FALSE;
+ }
first = queue->task;
}
queue->task = NULL;
+ silc_mutex_unlock(queue->lock);
return TRUE;
}
queue->task = silc_task_get_first(queue, next);
silc_free(old);
+ silc_mutex_unlock(queue->lock);
return TRUE;
}
old = old->prev;
- if (old == first)
+ if (old == first) {
+ silc_mutex_unlock(queue->lock);
return FALSE;
+ }
}
}
SilcTask next;
SILC_LOG_DEBUG(("Unregistering all tasks at once"));
- if (queue->task == NULL)
+ silc_mutex_lock(queue->lock);
+
+ if (!queue->task) {
+ silc_mutex_unlock(queue->lock);
return;
+ }
next = queue->task;
break;
next = next->next;
}
+
+ silc_mutex_unlock(queue->lock);
return;
}
SILC_LOG_DEBUG(("Unregister task by fd"));
- if (queue->task == NULL)
+ silc_mutex_lock(queue->lock);
+
+ if (!queue->task) {
+ silc_mutex_unlock(queue->lock);
return;
+ }
next = queue->task;
break;
next = next->next;
}
+
+ silc_mutex_unlock(queue->lock);
}
/* Unregister a task by callback function. This invalidates the task. */
SILC_LOG_DEBUG(("Unregister task by callback"));
- if (queue->task == NULL)
+ silc_mutex_lock(queue->lock);
+
+ if (!queue->task) {
+ silc_mutex_unlock(queue->lock);
return;
+ }
next = queue->task;
break;
next = next->next;
}
+
+ silc_mutex_unlock(queue->lock);
}
/* Unregister a task by context. This invalidates the task. */
SILC_LOG_DEBUG(("Unregister task by context"));
- if (queue->task == NULL)
+ silc_mutex_lock(queue->lock);
+
+ if (!queue->task) {
+ silc_mutex_unlock(queue->lock);
return;
+ }
next = queue->task;
break;
next = next->next;
}
+
+ silc_mutex_unlock(queue->lock);
}
/* Sets the I/O type of the task. The scheduler checks for this value