+/**
+ * Schedule a new task to be run as soon as possible with the
+ * (transitive) ignore-shutdown flag either explicitly set or
+ * explicitly enabled. This task (and all tasks created from it,
+ * other than by another call to this function) will either count or
+ * not count for the "lifeness" of the process. This API is only
+ * useful in a few special cases.
+ *
+ * @param lifeness #GNUNET_YES if the task counts for lifeness, #GNUNET_NO if not.
+ * @param task main function of the task
+ * @param task_cls closure of @a task
+ * @return unique task identifier for the job
+ * only valid until @a task is started!
+ */
+struct GNUNET_SCHEDULER_Task *
+GNUNET_SCHEDULER_add_now_with_lifeness (int lifeness,
+ GNUNET_SCHEDULER_TaskCallback task,
+ void *task_cls)
+{
+ struct GNUNET_SCHEDULER_Task *ret;
+
+ ret = GNUNET_SCHEDULER_add_now (task, task_cls);
+ ret->lifeness = lifeness;
+ return ret;
+}
+
+
+/**
+ * Schedule a new task to be run with a specified delay or when any of
+ * the specified file descriptor sets is ready. The delay can be used
+ * as a timeout on the socket(s) being ready. The task will be
+ * scheduled for execution once either the delay has expired or any of
+ * the socket operations is ready. This is the most general
+ * function of the "add" family. Note that the "prerequisite_task"
+ * must be satisfied in addition to any of the other conditions. In
+ * other words, the task will be started when
+ * <code>
+ * (prerequisite-run)
+ * && (delay-ready
+ * || any-rs-ready
+ * || any-ws-ready
+ * || shutdown-active )
+ * </code>
+ *
+ * @param delay how long should we wait? Use #GNUNET_TIME_UNIT_FOREVER_REL for "forever",
+ * which means that the task will only be run after we receive SIGTERM
+ * @param priority priority to use
+ * @param rfd file descriptor we want to read (can be -1)
+ * @param wfd file descriptors we want to write (can be -1)
+ * @param task main function of the task
+ * @param task_cls closure of @a task
+ * @return unique task identifier for the job
+ * only valid until @a task is started!
+ */
+#ifndef MINGW
+static struct GNUNET_SCHEDULER_Task *
+add_without_sets (struct GNUNET_TIME_Relative delay,
+ enum GNUNET_SCHEDULER_Priority priority,
+ int rfd,
+ int wfd,
+ GNUNET_SCHEDULER_TaskCallback task,
+ void *task_cls)
+{
+ struct GNUNET_SCHEDULER_Task *t;
+
+#if EXECINFO
+ void *backtrace_array[MAX_TRACE_DEPTH];
+#endif
+
+ GNUNET_assert (NULL != active_task);
+ GNUNET_assert (NULL != task);
+ t = GNUNET_new (struct GNUNET_SCHEDULER_Task);
+ t->callback = task;
+ t->callback_cls = task_cls;
+#if EXECINFO
+ t->num_backtrace_strings = backtrace (backtrace_array, MAX_TRACE_DEPTH);
+ t->backtrace_strings =
+ backtrace_symbols (backtrace_array, t->num_backtrace_strings);
+#endif
+#if DEBUG_FDS
+ if (-1 != rfd)
+ {
+ int flags = fcntl (rfd, F_GETFD);
+
+ if ((flags == -1) && (errno == EBADF))
+ {
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "Got invalid file descriptor %d!\n",
+ rfd);
+#if EXECINFO
+ int i;
+
+ for (i = 0; i < t->num_backtrace_strings; i++)
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Trace: %s\n",
+ t->backtrace_strings[i]);
+#endif
+ GNUNET_assert (0);
+ }
+ }
+ if (-1 != wfd)
+ {
+ int flags = fcntl (wfd, F_GETFD);
+
+ if (flags == -1 && errno == EBADF)
+ {
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "Got invalid file descriptor %d!\n",
+ wfd);
+#if EXECINFO
+ int i;
+
+ for (i = 0; i < t->num_backtrace_strings; i++)
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Trace: %s\n",
+ t->backtrace_strings[i]);
+#endif
+ GNUNET_assert (0);
+ }
+ }
+#endif
+ t->read_fd = rfd;
+ GNUNET_assert (wfd >= -1);
+ t->write_fd = wfd;
+#if PROFILE_DELAYS
+ t->start_time = GNUNET_TIME_absolute_get ();
+#endif
+ t->timeout = GNUNET_TIME_relative_to_absolute (delay);
+ t->priority = check_priority ((priority == GNUNET_SCHEDULER_PRIORITY_KEEP) ? current_priority : priority);
+ t->lifeness = current_lifeness;
+ GNUNET_CONTAINER_DLL_insert (pending_head,
+ pending_tail,
+ t);
+ max_priority_added = GNUNET_MAX (max_priority_added,
+ t->priority);
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Adding task %p\n",
+ t);
+#if EXECINFO
+ unsigned int i;
+
+ for (i = 0; i < t->num_backtrace_strings; i++)
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Task %p trace %d: %s\n",
+ t,
+ i,
+ t->backtrace_strings[i]);
+#endif
+ return t;
+}
+#endif
+