/*
- silcschedule.c
+ silcschedule.c
Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 1998 - 2001 Pekka Riikonen
+ Copyright (C) 1998 - 2002 Pekka Riikonen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
+ the Free Software Foundation; version 2 of the License.
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
return FALSE;
/* Dispatch all timeouts before going away */
+ SILC_SCHEDULE_LOCK(schedule);
silc_mutex_lock(schedule->timeout_queue->lock);
silc_schedule_dispatch_timeout(schedule, TRUE);
silc_mutex_unlock(schedule->timeout_queue->lock);
+ SILC_SCHEDULE_UNLOCK(schedule);
/* 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 */
static void silc_schedule_dispatch_nontimeout(SilcSchedule schedule)
{
SilcTask task;
- int i, last_fd = schedule->last_fd;
- SilcUInt32 fd;
+ int i;
+ SilcUInt32 fd, last_fd = schedule->last_fd;
+ SilcUInt16 revents;
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);
+ fd = schedule->fd_list[i].fd;
task = silc_task_find(schedule->fd_queue, fd);
+ revents = schedule->fd_list[i].revents;
/* If the task was found then execute its callbacks. If not then
execute all generic tasks for that fd. */
in the callback function, ie. it is not valid anymore. */
/* Is the task ready for reading */
- if (task->valid && schedule->fd_list[i].revents & SILC_TASK_READ) {
+ if (task->valid && revents & SILC_TASK_READ) {
silc_mutex_unlock(schedule->fd_queue->lock);
SILC_SCHEDULE_UNLOCK(schedule);
task->callback(schedule, schedule->app_context,
}
/* Is the task ready for writing */
- if (task->valid && schedule->fd_list[i].revents & SILC_TASK_WRITE) {
+ if (task->valid && revents & SILC_TASK_WRITE) {
silc_mutex_unlock(schedule->fd_queue->lock);
SILC_SCHEDULE_UNLOCK(schedule);
task->callback(schedule, schedule->app_context,
task = schedule->generic_queue->task;
while(1) {
- /* Validity of the task is checked always before and after
+ /* Validity of the task and fd is checked always before and after
execution beacuse the task might have been unregistered
in the callback function, ie. it is not valid anymore. */
/* Is the task ready for reading */
- if (task->valid && schedule->fd_list[i].revents & SILC_TASK_READ) {
+ if (task->valid && revents & SILC_TASK_READ &&
+ fd == schedule->fd_list[i].fd) {
silc_mutex_unlock(schedule->generic_queue->lock);
SILC_SCHEDULE_UNLOCK(schedule);
task->callback(schedule, schedule->app_context,
}
/* Is the task ready for writing */
- if (task->valid && schedule->fd_list[i].revents & SILC_TASK_WRITE) {
+ if (task->valid && revents & SILC_TASK_WRITE &&
+ fd == schedule->fd_list[i].fd) {
silc_mutex_unlock(schedule->generic_queue->lock);
SILC_SCHEDULE_UNLOCK(schedule);
task->callback(schedule, schedule->app_context,
if (!schedule->valid)
return NULL;
- SILC_LOG_DEBUG(("Registering new task, fd=%d type=%d priority=%d", fd,
- type, priority));
-
queue = SILC_SCHEDULE_GET_QUEUE(type);
/* If the task is generic task, we check whether this task has already
if (type == SILC_TASK_GENERIC) {
silc_mutex_lock(queue->lock);
+ SILC_LOG_DEBUG(("Registering new task, fd=%d type=%d priority=%d", fd,
+ type, priority));
+
if (queue->task) {
SilcTask task = queue->task;
while(1) {
}
newtask = silc_calloc(1, sizeof(*newtask));
+ if (!newtask)
+ return NULL;
+
+ SILC_LOG_DEBUG(("Registering new task %p, fd=%d type=%d priority=%d",
+ newtask, fd, type, priority));
+
newtask->fd = fd;
newtask->context = context;
newtask->callback = callback;
return TRUE;
}
- SILC_LOG_DEBUG(("Removing task"));
+ SILC_LOG_DEBUG(("Removing task %p", task));
/* Unregister the task */
old = first;