Implement a Full Domain Hash (FDH) for RSA signatures and blind signatures
[oweals/gnunet.git] / src / util / scheduler.c
index ec45889ea80d26221fd0266d62c003b1c1f5a92d..6405ea3369a0904f6e054fd2dae6e244756d7ff3 100644 (file)
@@ -1,6 +1,6 @@
 /*
       This file is part of GNUnet
-      (C) 2009-2013 Christian Grothoff (and other contributing authors)
+      Copyright (C) 2009-2013 GNUnet e.V.
 
       GNUnet is free software; you can redistribute it and/or modify
       it under the terms of the GNU General Public License as published
@@ -14,8 +14,8 @@
 
       You should have received a copy of the GNU General Public License
       along with GNUnet; see the file COPYING.  If not, write to the
-      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-      Boston, MA 02111-1307, USA.
+      Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+      Boston, MA 02110-1301, USA.
  */
 
 /**
@@ -151,6 +151,11 @@ struct GNUNET_SCHEDULER_Task
    */
   int lifeness;
 
+  /**
+   * Is this task in the ready list?
+   */
+  int in_ready_list;
+
 #if EXECINFO
   /**
    * Array of strings which make up a backtrace from the point when this
@@ -412,10 +417,11 @@ queue_ready_task (struct GNUNET_SCHEDULER_Task *task)
   enum GNUNET_SCHEDULER_Priority p = check_priority (task->priority);
 
   if (0 != (task->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
-    p = GNUNET_SCHEDULER_PRIORITY_SHUTDOWN;
+    p = task->priority = GNUNET_SCHEDULER_PRIORITY_SHUTDOWN;
   GNUNET_CONTAINER_DLL_insert (ready_head[p],
                                ready_tail[p],
                                task);
+  task->in_ready_list = GNUNET_YES;
   ready_count++;
 }
 
@@ -574,7 +580,7 @@ run_ready (struct GNUNET_NETWORK_FDSet *rs,
     if ((0 != (tc.reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) &&
         (-1 != pos->write_fd) &&
         (!GNUNET_NETWORK_fdset_test_native (ws, pos->write_fd)))
-      GNUNET_abort ();          // added to ready in previous select loop!
+      GNUNET_assert (0);          // added to ready in previous select loop!
     LOG (GNUNET_ERROR_TYPE_DEBUG,
         "Running task: %p\n",
          pos);
@@ -583,9 +589,9 @@ run_ready (struct GNUNET_NETWORK_FDSet *rs,
     unsigned int i;
 
     for (i = 0; i < pos->num_backtrace_strings; i++)
-      LOG (GNUNET_ERROR_TYPE_ERROR,
-           "Task %llu trace %u: %s\n",
-           pos->id,
+      LOG (GNUNET_ERROR_TYPE_DEBUG,
+           "Task %p trace %u: %s\n",
+           pos,
            i,
            pos->backtrace_strings[i]);
 #endif
@@ -751,9 +757,10 @@ GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_TaskCallback task,
 #endif
   current_priority = GNUNET_SCHEDULER_PRIORITY_DEFAULT;
   current_lifeness = GNUNET_YES;
-  GNUNET_SCHEDULER_add_continuation (task,
-                                     task_cls,
-                                     GNUNET_SCHEDULER_REASON_STARTUP);
+  GNUNET_SCHEDULER_add_with_reason_and_priority (task,
+                                                 task_cls,
+                                                 GNUNET_SCHEDULER_REASON_STARTUP,
+                                                 GNUNET_SCHEDULER_PRIORITY_DEFAULT);
   active_task = (void *) (long) -1;     /* force passing of sanity check */
   GNUNET_SCHEDULER_add_now_with_lifeness (GNUNET_NO,
                                           &GNUNET_OS_install_parent_control_handler,
@@ -774,9 +781,16 @@ GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_TaskCallback task,
       timeout = GNUNET_TIME_UNIT_ZERO;
     }
     if (NULL == scheduler_select)
-      ret = GNUNET_NETWORK_socket_select (rs, ws, NULL, timeout);
+      ret = GNUNET_NETWORK_socket_select (rs,
+                                          ws,
+                                          NULL,
+                                          timeout);
     else
-      ret = scheduler_select (scheduler_select_cls, rs, ws, NULL, timeout);
+      ret = scheduler_select (scheduler_select_cls,
+                              rs,
+                              ws,
+                              NULL,
+                              timeout);
     if (ret == GNUNET_SYSERR)
     {
       if (errno == EINTR)
@@ -795,15 +809,59 @@ GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_TaskCallback task,
                       "system");
 #endif
 #endif
-      GNUNET_abort ();
+#if DEBUG_FDS
+      struct GNUNET_SCHEDULER_Task *t;
+
+      for (t = pending_head; NULL != t; t = t->next)
+      {
+        if (-1 != t->read_fd)
+        {
+          int flags = fcntl (t->read_fd, F_GETFD);
+          if ((flags == -1) && (errno == EBADF))
+            {
+              LOG (GNUNET_ERROR_TYPE_ERROR,
+                   "Got invalid file descriptor %d!\n",
+                   t->read_fd);
+#if EXECINFO
+              unsigned int i;
+
+              for (i = 0; i < t->num_backtrace_strings; i++)
+                LOG (GNUNET_ERROR_TYPE_ERROR,
+                     "Trace: %s\n",
+                     t->backtrace_strings[i]);
+#endif
+            }
+        }
+        if (-1 != t->write_fd)
+          {
+            int flags = fcntl (t->write_fd, F_GETFD);
+            if ((flags == -1) && (errno == EBADF))
+              {
+                LOG (GNUNET_ERROR_TYPE_ERROR,
+                     "Got invalid file descriptor %d!\n",
+                     t->write_fd);
+#if EXECINFO
+                unsigned int i;
+
+                for (i = 0; i < t->num_backtrace_strings; i++)
+                  LOG (GNUNET_ERROR_TYPE_DEBUG,
+                       "Trace: %s\n",
+                       t->backtrace_strings[i]);
+#endif
+              }
+          }
+      }
+#endif
+      GNUNET_assert (0);
       break;
     }
+
     if ( (0 == ret) &&
          (0 == timeout.rel_value_us) &&
          (busy_wait_warning > 16) )
     {
       LOG (GNUNET_ERROR_TYPE_WARNING,
-           _("Looks like we're busy waiting...\n"));
+           "Looks like we're busy waiting...\n");
       short_wait (100);                /* mitigate */
     }
     check_ready (rs, ws);
@@ -899,7 +957,7 @@ GNUNET_SCHEDULER_cancel (struct GNUNET_SCHEDULER_Task *task)
   void *ret;
 
   GNUNET_assert (NULL != active_task);
-  if (GNUNET_SCHEDULER_REASON_NONE == task->reason)
+  if (! task->in_ready_list)
   {
     if ( (-1 == task->read_fd) &&
          (-1 == task->write_fd) &&
@@ -947,10 +1005,10 @@ GNUNET_SCHEDULER_cancel (struct GNUNET_SCHEDULER_Task *task)
  * @param priority priority to use for the task
  */
 void
-GNUNET_SCHEDULER_add_continuation_with_priority (GNUNET_SCHEDULER_TaskCallback task,
-                                                 void *task_cls,
-                                                enum GNUNET_SCHEDULER_Reason reason,
-                                                enum GNUNET_SCHEDULER_Priority priority)
+GNUNET_SCHEDULER_add_with_reason_and_priority (GNUNET_SCHEDULER_TaskCallback task,
+                                               void *task_cls,
+                                               enum GNUNET_SCHEDULER_Reason reason,
+                                               enum GNUNET_SCHEDULER_Priority priority)
 {
   struct GNUNET_SCHEDULER_Task *t;
 
@@ -984,25 +1042,6 @@ GNUNET_SCHEDULER_add_continuation_with_priority (GNUNET_SCHEDULER_TaskCallback t
 }
 
 
-/**
- * Continue the current execution with the given function.  This is
- * similar to the other "add" functions except that there is no delay
- * and the reason code can be specified.
- *
- * @param task main function of the task
- * @param task_cls closure for @a task
- * @param reason reason for task invocation
- */
-void
-GNUNET_SCHEDULER_add_continuation (GNUNET_SCHEDULER_TaskCallback task, void *task_cls,
-                                   enum GNUNET_SCHEDULER_Reason reason)
-{
-  GNUNET_SCHEDULER_add_continuation_with_priority (task, task_cls,
-                                                  reason,
-                                                  GNUNET_SCHEDULER_PRIORITY_DEFAULT);
-}
-
-
 /**
  * Schedule a new task to be run with a specified delay.  The task
  * will be scheduled for execution once the delay has expired.
@@ -1254,10 +1293,10 @@ add_without_sets (struct GNUNET_TIME_Relative delay,
            "Got invalid file descriptor %d!\n",
            rfd);
 #if EXECINFO
-      int i;
+      unsigned int i;
 
       for (i = 0; i < t->num_backtrace_strings; i++)
-        LOG (GNUNET_ERROR_TYPE_DEBUG,
+        LOG (GNUNET_ERROR_TYPE_ERROR,
              "Trace: %s\n",
              t->backtrace_strings[i]);
 #endif
@@ -1274,7 +1313,7 @@ add_without_sets (struct GNUNET_TIME_Relative delay,
            "Got invalid file descriptor %d!\n",
            wfd);
 #if EXECINFO
-      int i;
+      unsigned int i;
 
       for (i = 0; i < t->num_backtrace_strings; i++)
         LOG (GNUNET_ERROR_TYPE_DEBUG,