updates.
[silc.git] / lib / silcutil / silcschedule.c
index ad43f982a3b42b25f7ad13317beb82bcccd090f7..bd046a8f4e84044c0b2243f9c767c0a44dcf27bb 100644 (file)
@@ -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;
@@ -268,16 +271,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;
+  uint32 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 +290,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 +316,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 +334,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 +343,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);
        }
@@ -743,9 +747,10 @@ void silc_schedule_task_del(SilcSchedule schedule, SilcTask task)
 
 void silc_schedule_task_del_by_fd(SilcSchedule schedule, uint32 fd)
 {
+  SILC_LOG_DEBUG(("Unregister task by 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 +758,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 +769,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);
@@ -1056,7 +1065,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) {
@@ -1128,8 +1137,6 @@ static void silc_task_del_by_fd(SilcTaskQueue queue, uint32 fd)
 {
   SilcTask next;
 
-  SILC_LOG_DEBUG(("Unregister task by fd"));
-
   silc_mutex_lock(queue->lock);
 
   if (!queue->task) {
@@ -1155,8 +1162,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 +1186,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) {