Integer type name change.
[silc.git] / lib / silcutil / silcschedule.c
index ad43f982a3b42b25f7ad13317beb82bcccd090f7..884091838213d1b0f92dbf7600b0fcb66e33780a 100644 (file)
@@ -28,7 +28,7 @@ typedef struct SilcTaskQueueStruct *SilcTaskQueue;
 /* System specific routines. Implemented under unix/ and win32/. */
 
 /* System specific select(). Returns same values as normal select(). */
-int silc_select(SilcScheduleFd fds, uint32 fds_count, struct timeval *timeout);
+int silc_select(SilcScheduleFd fds, SilcUInt32 fds_count, struct timeval *timeout);
 
 /* Initializes the wakeup of the scheduler. In multi-threaded environment
    the scheduler needs to be wakenup when tasks are added or removed from
@@ -49,7 +49,7 @@ void silc_schedule_wakeup_internal(void *context);
 
 static void silc_task_queue_alloc(SilcTaskQueue *queue);
 static void silc_task_queue_free(SilcTaskQueue queue);
-static SilcTask silc_task_find(SilcTaskQueue queue, uint32 fd);
+static SilcTask silc_task_find(SilcTaskQueue queue, SilcUInt32 fd);
 static SilcTask silc_task_add(SilcTaskQueue queue, SilcTask newtask, 
                              SilcTaskPriority priority);
 static SilcTask silc_task_get_first(SilcTaskQueue queue, SilcTask first);
@@ -61,7 +61,7 @@ static int silc_schedule_task_timeout_compare(struct timeval *smaller,
 static void silc_task_del_by_context(SilcTaskQueue queue, void *context);
 static void silc_task_del_by_callback(SilcTaskQueue queue,
                                      SilcTaskCallback callback);
-static void silc_task_del_by_fd(SilcTaskQueue queue, uint32 fd);
+static void silc_task_del_by_fd(SilcTaskQueue queue, SilcUInt32 fd);
 
 /* Returns the task queue by task type */
 #define SILC_SCHEDULE_GET_QUEUE(type)                                  \
@@ -71,7 +71,7 @@ static void silc_task_del_by_fd(SilcTaskQueue queue, uint32 fd);
 
 /* SILC Task object. Represents one task in the scheduler. */
 struct SilcTaskStruct {
-  uint32 fd;
+  SilcUInt32 fd;
   struct timeval timeout;
   SilcTaskCallback callback;
   void *context;
@@ -131,8 +131,8 @@ struct SilcTaskQueueStruct {
        List of file descriptors the scheduler is supposed to be listenning.
        This is updated internally.
 
-   uint32 max_fd
-   uint32 last_fd
+   SilcUInt32 max_fd
+   SilcUInt32 last_fd
 
        Size of the fd_list list. There can be `max_fd' many tasks in
        the scheduler at once. The `last_fd' is the last valid entry
@@ -172,8 +172,8 @@ struct SilcScheduleStruct {
   SilcTaskQueue timeout_queue;
   SilcTaskQueue generic_queue;
   SilcScheduleFd fd_list;
-  uint32 max_fd;
-  uint32 last_fd;
+  SilcUInt32 max_fd;
+  SilcUInt32 last_fd;
   struct timeval *timeout;
   bool valid;
   void *wakeup;
@@ -200,6 +200,9 @@ SilcSchedule silc_schedule_init(int max_tasks)
   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;
@@ -247,6 +250,20 @@ bool silc_schedule_uninit(SilcSchedule schedule)
   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). */
@@ -254,9 +271,7 @@ bool silc_schedule_uninit(SilcSchedule schedule)
 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
@@ -268,16 +283,18 @@ void silc_schedule_stop(SilcSchedule schedule)
 static void silc_schedule_dispatch_nontimeout(SilcSchedule schedule)
 {
   SilcTask task;
-  int i;
+  int i, last_fd = schedule->last_fd;
+  SilcUInt32 fd;
 
-  for (i = 0; i <= schedule->last_fd; i++) {
+  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. */
@@ -285,7 +302,6 @@ static void silc_schedule_dispatch_nontimeout(SilcSchedule schedule)
       /* 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) {
@@ -312,6 +328,8 @@ static void silc_schedule_dispatch_nontimeout(SilcSchedule schedule)
     } 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);
@@ -328,8 +346,7 @@ static void silc_schedule_dispatch_nontimeout(SilcSchedule schedule)
        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);
        }
@@ -338,8 +355,7 @@ static void silc_schedule_dispatch_nontimeout(SilcSchedule schedule)
        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);
        }
@@ -605,7 +621,7 @@ void silc_schedule_wakeup(SilcSchedule schedule)
 
 /* Add new task to the scheduler */
 
-SilcTask silc_schedule_task_add(SilcSchedule schedule, uint32 fd,
+SilcTask silc_schedule_task_add(SilcSchedule schedule, SilcUInt32 fd,
                                SilcTaskCallback callback, void *context, 
                                long seconds, long useconds, 
                                SilcTaskType type, 
@@ -741,11 +757,12 @@ void silc_schedule_task_del(SilcSchedule schedule, SilcTask task)
 
 /* Remove task by fd */
 
-void silc_schedule_task_del_by_fd(SilcSchedule schedule, uint32 fd)
+void silc_schedule_task_del_by_fd(SilcSchedule schedule, SilcUInt32 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);
-  silc_task_del_by_fd(schedule->generic_queue, fd);
 }
 
 /* Remove task by task callback. */
@@ -753,6 +770,8 @@ void silc_schedule_task_del_by_fd(SilcSchedule schedule, uint32 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);
@@ -762,6 +781,8 @@ void silc_schedule_task_del_by_callback(SilcSchedule schedule,
 
 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);
@@ -772,7 +793,7 @@ void silc_schedule_task_del_by_context(SilcSchedule schedule, void *context)
    one file descriptor to set different iomasks. */
 
 void silc_schedule_set_listen_fd(SilcSchedule schedule,
-                                uint32 fd, SilcTaskEvent iomask)
+                                SilcUInt32 fd, SilcTaskEvent iomask)
 {
   int i;
   bool found = FALSE;
@@ -804,12 +825,14 @@ void silc_schedule_set_listen_fd(SilcSchedule schedule,
 
 /* Removes a file descriptor from listen list. */
 
-void silc_schedule_unset_listen_fd(SilcSchedule schedule, uint32 fd)
+void silc_schedule_unset_listen_fd(SilcSchedule schedule, SilcUInt32 fd)
 {
   int i;
 
   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;
@@ -840,7 +863,7 @@ static void silc_task_queue_free(SilcTaskQueue queue)
 
 /* Return task by its fd. */
 
-static SilcTask silc_task_find(SilcTaskQueue queue, uint32 fd)
+static SilcTask silc_task_find(SilcTaskQueue queue, SilcUInt32 fd)
 {
   SilcTask next;
 
@@ -1056,7 +1079,7 @@ static int silc_schedule_task_remove(SilcTaskQueue queue, SilcTask task)
 {
   SilcTask first, old, next;
 
-  if (!queue)
+  if (!queue || !task)
     return FALSE;
 
   if (!queue->task) {
@@ -1124,12 +1147,10 @@ static int silc_schedule_task_timeout_compare(struct timeval *smaller,
   return FALSE;
 }
 
-static void silc_task_del_by_fd(SilcTaskQueue queue, uint32 fd)
+static void silc_task_del_by_fd(SilcTaskQueue queue, SilcUInt32 fd)
 {
   SilcTask next;
 
-  SILC_LOG_DEBUG(("Unregister task by fd"));
-
   silc_mutex_lock(queue->lock);
 
   if (!queue->task) {
@@ -1155,8 +1176,6 @@ static void silc_task_del_by_callback(SilcTaskQueue queue,
 {
   SilcTask next;
 
-  SILC_LOG_DEBUG(("Unregister task by callback"));
-
   silc_mutex_lock(queue->lock);
 
   if (!queue->task) {
@@ -1181,8 +1200,6 @@ static void silc_task_del_by_context(SilcTaskQueue queue, void *context)
 {
   SilcTask next;
 
-  SILC_LOG_DEBUG(("Unregister task by context"));
-
   silc_mutex_lock(queue->lock);
 
   if (!queue->task) {