silc_task_queue_alloc(&schedule->timeout_queue);
silc_task_queue_alloc(&schedule->generic_queue);
+ if (!max_tasks)
+ max_tasks = 200;
+
/* Initialize the scheduler */
schedule->fd_list = silc_calloc(max_tasks, sizeof(*schedule->fd_list));
schedule->max_fd = max_tasks;
return TRUE;
}
+/* Enlarge the capabilities of the scheduler to handle tasks to `max_tasks'. */
+
+bool silc_schedule_reinit(SilcSchedule schedule, int max_tasks)
+{
+ silc_mutex_lock(schedule->lock);
+ if (schedule->max_fd <= max_tasks)
+ return FALSE;
+ schedule->fd_list = silc_realloc(schedule->fd_list,
+ (sizeof(*schedule->fd_list) * max_tasks));
+ schedule->max_fd = max_tasks;
+ silc_mutex_unlock(schedule->lock);
+ return TRUE;
+}
+
/* Stops the schedule even if it is not supposed to be stopped yet.
After calling this, one should call silc_schedule_uninit (after the
silc_schedule has returned). */
void silc_schedule_stop(SilcSchedule schedule)
{
SILC_LOG_DEBUG(("Stopping scheduler"));
- silc_mutex_lock(schedule->lock);
schedule->valid = FALSE;
- silc_mutex_unlock(schedule->lock);
}
/* Executes nontimeout tasks. It then checks whether any of ther fd tasks
{
SilcTask task;
int i, last_fd = schedule->last_fd;
+ uint32 fd;
for (i = 0; i <= last_fd; i++) {
if (schedule->fd_list[i].events == 0)
continue;
+ fd = schedule->fd_list[i].fd;
+
/* First check whether this fd has task in the fd queue */
silc_mutex_lock(schedule->fd_queue->lock);
- task = silc_task_find(schedule->fd_queue, schedule->fd_list[i].fd);
- silc_mutex_unlock(schedule->fd_queue->lock);
+ task = silc_task_find(schedule->fd_queue, fd);
/* If the task was found then execute its callbacks. If not then
execute all generic tasks for that fd. */
/* 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. */
- silc_mutex_lock(schedule->fd_queue->lock);
/* Is the task ready for reading */
if (task->valid && schedule->fd_list[i].revents & SILC_TASK_READ) {
} else {
/* Run generic tasks for this fd. */
+ silc_mutex_unlock(schedule->fd_queue->lock);
+
silc_mutex_lock(schedule->generic_queue->lock);
if (!schedule->generic_queue->task) {
silc_mutex_unlock(schedule->generic_queue->lock);
if (task->valid && schedule->fd_list[i].revents & SILC_TASK_READ) {
silc_mutex_unlock(schedule->generic_queue->lock);
silc_mutex_unlock(schedule->lock);
- task->callback(schedule, SILC_TASK_READ, schedule->fd_list[i].fd,
- task->context);
+ task->callback(schedule, SILC_TASK_READ, fd, task->context);
silc_mutex_lock(schedule->lock);
silc_mutex_lock(schedule->generic_queue->lock);
}
if (task->valid && schedule->fd_list[i].revents & SILC_TASK_WRITE) {
silc_mutex_unlock(schedule->generic_queue->lock);
silc_mutex_unlock(schedule->lock);
- task->callback(schedule, SILC_TASK_WRITE, schedule->fd_list[i].fd,
- task->context);
+ task->callback(schedule, SILC_TASK_WRITE, fd, task->context);
silc_mutex_lock(schedule->lock);
silc_mutex_lock(schedule->generic_queue->lock);
}
void silc_schedule_task_del_by_fd(SilcSchedule schedule, uint32 fd)
{
+ SILC_LOG_DEBUG(("Unregister task by fd %d", fd));
+
silc_task_del_by_fd(schedule->timeout_queue, fd);
silc_task_del_by_fd(schedule->fd_queue, fd);
}
void silc_schedule_task_del_by_callback(SilcSchedule schedule,
SilcTaskCallback callback)
{
+ SILC_LOG_DEBUG(("Unregister task by callback"));
+
silc_task_del_by_callback(schedule->timeout_queue, callback);
silc_task_del_by_callback(schedule->fd_queue, callback);
silc_task_del_by_callback(schedule->generic_queue, callback);
void silc_schedule_task_del_by_context(SilcSchedule schedule, void *context)
{
+ SILC_LOG_DEBUG(("Unregister task by context"));
+
silc_task_del_by_context(schedule->timeout_queue, context);
silc_task_del_by_context(schedule->fd_queue, context);
silc_task_del_by_context(schedule->generic_queue, context);
silc_mutex_lock(schedule->lock);
+ SILC_LOG_DEBUG(("Unset listen fd %d", fd));
+
for (i = 0; i < schedule->max_fd; i++)
if (schedule->fd_list[i].fd == fd) {
schedule->fd_list[i].fd = 0;
{
SilcTask next;
- SILC_LOG_DEBUG(("Unregister task by fd"));
-
silc_mutex_lock(queue->lock);
if (!queue->task) {
{
SilcTask next;
- SILC_LOG_DEBUG(("Unregister task by callback"));
-
silc_mutex_lock(queue->lock);
if (!queue->task) {
{
SilcTask next;
- SILC_LOG_DEBUG(("Unregister task by context"));
-
silc_mutex_lock(queue->lock);
if (!queue->task) {