Splitted SILC core library. Core library includes now only
[silc.git] / lib / silccore / silctask.c
diff --git a/lib/silccore/silctask.c b/lib/silccore/silctask.c
deleted file mode 100644 (file)
index cc177dc..0000000
+++ /dev/null
@@ -1,551 +0,0 @@
-/*
-
-  silctask.c
-
-  Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
-
-  Copyright (C) 1998 - 2000 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.
-  
-  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
-  GNU General Public License for more details.
-
-*/
-/*
- * $Id$
- * $Log$
- * Revision 1.2  2000/07/05 06:06:35  priikone
- *     Global cosmetic change.
- *
- * Revision 1.1.1.1  2000/06/27 11:36:55  priikone
- *     Imported from internal CVS/Added Log headers.
- *
- *
- */
-
-#include "silcincludes.h"
-
-/* Allocates a new task queue into the Silc. If 'valid' is TRUE the
-   queue becomes valid task queue. If it is FALSE scheduler will skip
-   the queue. */
-
-void silc_task_queue_alloc(SilcTaskQueue *new, int valid)
-{
-
-  SILC_LOG_DEBUG(("Allocating new task queue"));
-
-  *new = silc_calloc(1, sizeof(**new));
-
-  /* Set the pointers */
-  (*new)->valid = valid;
-  (*new)->task = NULL;
-  (*new)->register_task = silc_task_register;
-  (*new)->unregister_task = silc_task_unregister;
-  (*new)->set_iotype = silc_task_set_iotype;
-  (*new)->reset_iotype = silc_task_reset_iotype;
-}
-
-/* Free's a task queue. */
-
-void silc_task_queue_free(SilcTaskQueue old)
-{
-  if (old)
-    silc_free(old);
-}
-
-/* Adds a non-timeout task into the task queue. This function is used
-   by silc_task_register function. Returns a pointer to the registered 
-   task. */
-
-SilcTask silc_task_add(SilcTaskQueue queue, SilcTask new, 
-                      SilcTaskPriority priority)
-{
-  SilcTask task, next, prev;
-
-  /* Take the first task in the queue */
-  task = queue->task;
-
-  switch(priority) {
-  case SILC_TASK_PRI_LOW:
-    /* Lowest priority. The task is added at the end of the list. */
-    prev = task->prev;
-    new->prev = prev;
-    new->next = task;
-    prev->next = new;
-    task->prev = new;
-    break;
-  case SILC_TASK_PRI_NORMAL:
-    /* Normal priority. The task is added before lower priority tasks
-       but after tasks with higher priority. */
-    prev = task->prev;
-    while(prev != task) {
-      if (prev->priority > SILC_TASK_PRI_LOW &&
-         prev->priority <= SILC_TASK_PRI_REALTIME)
-       break;
-      prev = prev->prev;
-    }
-    if (prev == task) {
-      /* There are only lower priorities in the list, we will
-        sit before them and become the first task in the queue. */
-      prev = task->prev;
-      new->prev = prev;
-      new->next = task;
-      task->prev = new;
-      prev->next = new;
-
-      /* We are now the first task in queue */
-      queue->task = new;
-    } else {
-      /* Found a spot from the list, add the task to the list. */
-      next = prev->next;
-      new->prev = prev;
-      new->next = next;
-      prev->next = new;
-      next->prev = new;
-    }
-    break;
-  case SILC_TASK_PRI_HIGH:
-    /* High priority. The task is added before lower priority tasks
-       but after tasks with higher priority. */
-    prev = task->prev;
-    while(prev != task) {
-      if (prev->priority > SILC_TASK_PRI_NORMAL &&
-         prev->priority <= SILC_TASK_PRI_REALTIME)
-       break;
-      prev = prev->prev;
-    }
-    if (prev == task) {
-      /* There are only lower priorities in the list, we will
-        sit before them and become the first task in the queue. */
-      prev = task->prev;
-      new->prev = prev;
-      new->next = task;
-      task->prev = new;
-      prev->next = new;
-
-      /* We are now the first task in queue */
-      queue->task = new;
-    } else {
-      /* Found a spot from the list, add the task to the list. */
-      next = prev->next;
-      new->prev = prev;
-      new->next = next;
-      prev->next = new;
-      next->prev = new;
-    }
-    break;
-  case SILC_TASK_PRI_REALTIME:
-    /* Highest priority. The task is added at the head of the list. 
-       The last registered task is added to the very head of the list
-       thus we get the LIFO (Last-In-First-Out) order. */
-    prev = task->prev;
-    new->prev = prev;
-    new->next = task;
-    prev->next = new;
-    task->prev = new;
-
-    /* We are the first task in the queue */
-    queue->task = new;
-    break;
-  default:
-    silc_free(new);
-    return NULL;
-  }
-
-  return new;
-}
-
-/* Adds a timeout task into the task queue. This function is used by
-   silc_task_register function. Returns a pointer to the registered 
-   task. Timeout tasks are sorted by their timeout value in ascending
-   order. The priority matters if there are more than one task with
-   same timeout. */
-
-SilcTask silc_task_add_timeout(SilcTaskQueue queue, SilcTask new,
-                              SilcTaskPriority priority)
-{
-  SilcTask task, prev, next;
-
-  /* Take the first task in the queue */
-  task = queue->task;
-
-  /* Take last task from the list */
-  prev = task->prev;
-    
-  switch(priority) {
-  case SILC_TASK_PRI_LOW:
-    /* Lowest priority. The task is added at the end of the list. */
-    while(prev != task) {
-
-      /* If we have longer timeout than with the task head of us
-        we have found our spot. */
-      if (silc_task_timeout_compare(&prev->timeout, &new->timeout))
-       break;
-
-      /* If we are equal size of timeout we will be after it. */
-      if (!silc_task_timeout_compare(&new->timeout, &prev->timeout))
-       break;
-
-      /* We have shorter timeout, compare to next one. */
-      prev = prev->prev;
-    }
-    /* Found a spot from the list, add the task to the list. */
-    next = prev->next;
-    new->prev = prev;
-    new->next = next;
-    prev->next = new;
-    next->prev = new;
-    
-    if (prev == task) {
-      /* Check if we are going to be the first task in the queue */
-      if (silc_task_timeout_compare(&prev->timeout, &new->timeout))
-       break;
-      if (!silc_task_timeout_compare(&new->timeout, &prev->timeout))
-       break;
-
-      /* We are now the first task in queue */
-      queue->task = new;
-    }
-    break;
-  case SILC_TASK_PRI_NORMAL:
-    /* Normal priority. The task is added before lower priority tasks
-       but after tasks with higher priority. */
-    while(prev != task) {
-
-      /* If we have longer timeout than with the task head of us
-        we have found our spot. */
-      if (silc_task_timeout_compare(&prev->timeout, &new->timeout))
-       break;
-
-      /* If we are equal size of timeout, priority kicks in place. */
-      if (!silc_task_timeout_compare(&new->timeout, &prev->timeout))
-       if (prev->priority >= SILC_TASK_PRI_NORMAL)
-         break;
-
-      /* We have shorter timeout or higher priority, compare to next one. */
-      prev = prev->prev;
-    }
-    /* Found a spot from the list, add the task to the list. */
-    next = prev->next;
-    new->prev = prev;
-    new->next = next;
-    prev->next = new;
-    next->prev = new;
-    
-    if (prev == task) {
-      /* Check if we are going to be the first task in the queue */
-      if (silc_task_timeout_compare(&prev->timeout, &new->timeout))
-       break;
-      if (!silc_task_timeout_compare(&new->timeout, &prev->timeout))
-       if (prev->priority >= SILC_TASK_PRI_NORMAL)
-         break;
-
-      /* We are now the first task in queue */
-      queue->task = new;
-    }
-    break;
-  case SILC_TASK_PRI_HIGH:
-    /* High priority. The task is added before lower priority tasks
-       but after tasks with higher priority. */
-    while(prev != task) {
-
-      /* If we have longer timeout than with the task head of us
-        we have found our spot. */
-      if (silc_task_timeout_compare(&prev->timeout, &new->timeout))
-       break;
-
-      /* If we are equal size of timeout, priority kicks in place. */
-      if (!silc_task_timeout_compare(&new->timeout, &prev->timeout))
-       if (prev->priority >= SILC_TASK_PRI_HIGH)
-         break;
-
-      /* We have shorter timeout or higher priority, compare to next one. */
-      prev = prev->prev;
-    }
-    /* Found a spot from the list, add the task to the list. */
-    next = prev->next;
-    new->prev = prev;
-    new->next = next;
-    prev->next = new;
-    next->prev = new;
-    
-    if (prev == task) {
-      /* Check if we are going to be the first task in the queue */
-      if (silc_task_timeout_compare(&prev->timeout, &new->timeout))
-       break;
-      if (!silc_task_timeout_compare(&new->timeout, &prev->timeout))
-       if (prev->priority >= SILC_TASK_PRI_HIGH)
-         break;
-
-      /* We are now the first task in queue */
-      queue->task = new;
-    }
-    break;
-  case SILC_TASK_PRI_REALTIME:
-    /* Highest priority. The task is added at the head of the list. 
-       The last registered task is added to the very head of the list
-       thus we get the LIFO (Last-In-First-Out) order. */
-    next = task->next;
-    while(next != task) {
-
-      /* If we have shorter timeout than the next task we've found
-        our spot. */
-      if (silc_task_timeout_compare(&new->timeout, &next->timeout))
-       break;
-
-      /* If we are equal size of timeout we will be first. */
-      if (!silc_task_timeout_compare(&next->timeout, &new->timeout))
-       break;
-
-      /* We have longer timeout, compare to next one. */
-      next = next->next;
-    }
-    /* Found a spot from the list, add the task to the list. */
-    prev = next->prev;
-    new->next = next;
-    new->prev = prev;
-    prev->next = new;
-    next->prev = new;
-    
-    if (next == task) {
-      /* Check if we are going to be the first task in the queue */
-      if (silc_task_timeout_compare(&next->timeout, &new->timeout))
-       break;
-
-      /* We are now the first task in queue */
-      queue->task = new;
-    }
-  default:
-    silc_free(new);
-    return NULL;
-  }
-
-  return new;
-}
-
-/* Registers a new task into the task queue. The task becomes valid
-   automatically when it is registered. Returns a pointer to the 
-   registered task. */
-
-SilcTask silc_task_register(SilcTaskQueue queue, int fd, 
-                           SilcTaskCallback cb, void *context, 
-                           long seconds, long useconds, 
-                           SilcTaskType type, SilcTaskPriority priority)
-{
-  SilcTask new;
-  int timeout = 0;
-
-  SILC_LOG_DEBUG(("Registering new task, fd=%d type=%d priority=%d", 
-                 fd, type, priority));
-
-  /* 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(fd, (1L << SILC_TASK_READ));
-       return task;
-      }
-
-      if (queue->task == task->next)
-       break;
-      
-      task = task->next;
-    }
-  }
-
-  new = silc_calloc(1, sizeof(*new));
-  new->fd = fd;
-  new->context = context;
-  new->callback = cb;
-  new->valid = TRUE;
-  new->priority = priority;
-  new->iomask = (1L << SILC_TASK_READ);
-  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(fd, (1L << SILC_TASK_READ));
-
-  /* Create timeout if marked to be timeout task */
-  if (((seconds + useconds) > 0) && (type == SILC_TASK_TIMEOUT)) {
-    gettimeofday(&new->timeout, NULL);
-    new->timeout.tv_sec += seconds + (useconds / 1000000L);
-    new->timeout.tv_usec += (useconds % 1000000L);
-    if (new->timeout.tv_usec > 999999L) {
-      new->timeout.tv_sec += 1;
-      new->timeout.tv_usec -= 1000000L;
-    }
-    timeout = 1;
-  }
-
-  /* Is this first task of the queue? */
-  if (queue->task == NULL) {
-    queue->task = new;
-    return new;
-  }
-
-  if (timeout)
-    return silc_task_add_timeout(queue, new, priority);
-  else
-    return silc_task_add(queue, new, priority);
-}
-
-/* Removes (unregisters) a task from particular task queue. This function
-   is used internally by scheduler. One should not call this function
-   to unregister tasks, instead silc_task_unregister_task function
-   should be used. */
-
-int silc_task_remove(SilcTaskQueue queue, SilcTask task)
-{
-  SilcTask first, old, next;
-
-  if (!queue || !queue->task)
-    return FALSE;
-
-  first = queue->task;
-
-  /* Unregister all tasks in queue */
-  if (task == SILC_ALL_TASKS) {
-    SILC_LOG_DEBUG(("Removing all tasks at once"));
-    next = first;
-
-    while(1) {
-      next = next->next;
-      silc_free(next->prev);
-      if (next == first)
-       break;
-    }
-
-    queue->task = NULL;
-    return TRUE;
-  }
-
-  SILC_LOG_DEBUG(("Removing task"));
-
-  /* Unregister the task */
-  old = first;
-  while(1) {
-    if (old == task) {
-      SilcTask prev, next;
-
-      prev = old->prev;
-      next = old->next;
-      prev->next = next;
-      next->prev = prev;
-
-      if (prev == old && next == old)
-       queue->task = NULL;
-      if (queue->task == old)
-       queue->task = next;
-
-      silc_free(old);
-      return TRUE;
-    }
-    old = old->next;
-
-    if (old == first)
-      return FALSE;
-  }
-}
-
-/* Unregisters a task from the task queue. This is the unregister_task
-   function pointer in task queue object. One should use this function
-   to unregister tasks. This function invalidates the task. */
-
-void silc_task_unregister(SilcTaskQueue queue, SilcTask task)
-{
-
-  /* Unregister all tasks */
-  if (task == SILC_ALL_TASKS) {
-    SilcTask next;
-    SILC_LOG_DEBUG(("Unregistering all tasks at once"));
-
-    if (queue->task == NULL)
-      return;
-
-    next = queue->task;
-    
-    while(1) {
-      if (next->valid)
-       next->valid = FALSE;
-      if (queue->task == next->next)
-       break;
-      next = next->next;
-    }
-    return;
-  }
-
-  SILC_LOG_DEBUG(("Unregistering task"));
-
-  /* Unregister the specific task */
-  if (task->valid)
-    task->valid = FALSE;
-}
-
-/* Unregister a task by file descriptor. This invalidates the task. */
-
-void silc_task_unregister_by_fd(SilcTaskQueue queue, int fd)
-{
-  SilcTask next;
-
-  SILC_LOG_DEBUG(("Unregister task by fd"));
-
-  if (queue->task == NULL)
-    return;
-
-  next = queue->task;
-
-  while(1) {
-    if (next->fd == fd)
-      next->valid = FALSE;
-    if (queue->task == next->next)
-      break;
-    next = next->next;
-  }
-}
-
-/* Sets the I/O mask for the task. Only one I/O type can be set at a
-   time. */
-
-void silc_task_set_iotype(SilcTask task, int type)
-{
-  task->iomask |= (1L << type);
-}
-
-/* Resets the I/O mask to the type sent as argument. */
-
-void silc_task_reset_iotype(SilcTask task, int type)
-{
-  task->iomask = (1L << type);
-}
-
-/* Compare two time values. If the first argument is smaller than the
-   second this function returns TRUE. */
-
-int silc_task_timeout_compare(struct timeval *smaller, 
-                             struct timeval *bigger)
-{
-  if ((smaller->tv_sec < bigger->tv_sec) ||
-      ((smaller->tv_sec == bigger->tv_sec) &&
-       (smaller->tv_usec < bigger->tv_usec)))
-    return TRUE;
-
-  return FALSE;
-}