/*
This file is part of GNUnet
- (C) 2009-2013 Christian Grothoff (and other contributing authors)
+ Copyright (C) 2009-2016 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
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.
*/
/**
*/
int lifeness;
+ /**
+ * Is this task run on shutdown?
+ */
+ int on_shutdown;
+
/**
* Is this task in the ready list?
*/
*/
static struct GNUNET_SCHEDULER_Task *pending_tail;
+/**
+ * Head of list of tasks waiting for shutdown.
+ */
+static struct GNUNET_SCHEDULER_Task *shutdown_head;
+
+/**
+ * Tail of list of tasks waiting for shutdown.
+ */
+static struct GNUNET_SCHEDULER_Task *shutdown_tail;
+
/**
* List of tasks waiting ONLY for a timeout event.
* Sorted by timeout (earliest first). Used so that
*/
static GNUNET_SCHEDULER_select scheduler_select;
+/**
+ * Task context of the current task.
+ */
+static struct GNUNET_SCHEDULER_TaskContext tc;
+
/**
* Closure for #scheduler_select.
*/
{
enum GNUNET_SCHEDULER_Priority p = check_priority (task->priority);
- if (0 != (task->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
- p = GNUNET_SCHEDULER_PRIORITY_SHUTDOWN;
GNUNET_CONTAINER_DLL_insert (ready_head[p],
ready_tail[p],
task);
/**
- * Request the shutdown of a scheduler. Marks all currently
- * pending tasks as ready because of shutdown. This will
- * cause all tasks to run (as soon as possible, respecting
- * priorities and prerequisite tasks). Note that tasks
- * scheduled AFTER this call may still be delayed arbitrarily.
- *
- * Note that we don't move the tasks into the ready queue yet;
- * check_ready() will do that later, possibly adding additional
- * readiness-factors
+ * Request the shutdown of a scheduler. Marks all tasks
+ * awaiting shutdown as ready. Note that tasks
+ * scheduled with #GNUNET_SCHEDULER_add_shutdown() AFTER this call
+ * will be delayed until the next shutdown signal.
*/
void
GNUNET_SCHEDULER_shutdown ()
{
struct GNUNET_SCHEDULER_Task *pos;
- int i;
- for (pos = pending_timeout_head; NULL != pos; pos = pos->next)
- pos->reason |= GNUNET_SCHEDULER_REASON_SHUTDOWN;
- for (pos = pending_head; NULL != pos; pos = pos->next)
+ while (NULL != (pos = shutdown_head))
+ {
+ GNUNET_CONTAINER_DLL_remove (shutdown_head,
+ shutdown_tail,
+ pos);
pos->reason |= GNUNET_SCHEDULER_REASON_SHUTDOWN;
- for (i = 0; i < GNUNET_SCHEDULER_PRIORITY_COUNT; i++)
- for (pos = ready_head[i]; NULL != pos; pos = pos->next)
- pos->reason |= GNUNET_SCHEDULER_REASON_SHUTDOWN;
+ queue_ready_task (pos);
+ }
}
}
+/**
+ * Output stack trace of task @a t.
+ *
+ * @param t task to dump stack trace of
+ */
+static void
+dump_backtrace (struct GNUNET_SCHEDULER_Task *t)
+{
+#if EXECINFO
+ unsigned int i;
+
+ for (i = 0; i < t->num_backtrace_strings; i++)
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Task %p trace %u: %s\n",
+ t,
+ i,
+ t->backtrace_strings[i]);
+#endif
+}
+
+
/**
* Run at least one task in the highest-priority queue that is not
* empty. Keep running tasks until we are either no longer running
{
enum GNUNET_SCHEDULER_Priority p;
struct GNUNET_SCHEDULER_Task *pos;
- struct GNUNET_SCHEDULER_TaskContext tc;
max_priority_added = GNUNET_SCHEDULER_PRIORITY_KEEP;
do
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);
- pos->callback (pos->callback_cls, &tc);
-#if EXECINFO
- 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,
- i,
- pos->backtrace_strings[i]);
-#endif
+ pos->callback (pos->callback_cls);
+ dump_backtrace (pos);
active_task = NULL;
destroy_task (pos);
tasks_run++;
/**
- * Check if the system is still life. Trigger shutdown if we
+ * Check if the system is still alive. Trigger shutdown if we
* have tasks, but none of them give us lifeness.
*
* @return #GNUNET_OK to continue the main loop,
for (t = pending_head; NULL != t; t = t->next)
if (t->lifeness == GNUNET_YES)
return GNUNET_OK;
+ for (t = shutdown_head; NULL != t; t = t->next)
+ if (t->lifeness == GNUNET_YES)
+ return GNUNET_OK;
for (t = pending_timeout_head; NULL != t; t = t->next)
if (t->lifeness == GNUNET_YES)
return GNUNET_OK;
- if ((NULL != pending_head) || (NULL != pending_timeout_head))
+ if (NULL != shutdown_head)
{
GNUNET_SCHEDULER_shutdown ();
return GNUNET_OK;
my_pid = getpid ();
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Registering signal handlers\n");
- shc_int = GNUNET_SIGNAL_handler_install (SIGINT, &sighandler_shutdown);
- shc_term = GNUNET_SIGNAL_handler_install (SIGTERM, &sighandler_shutdown);
+ shc_int = GNUNET_SIGNAL_handler_install (SIGINT,
+ &sighandler_shutdown);
+ shc_term = GNUNET_SIGNAL_handler_install (SIGTERM,
+ &sighandler_shutdown);
#if (SIGTERM != GNUNET_TERM_SIG)
- shc_gterm = GNUNET_SIGNAL_handler_install (GNUNET_TERM_SIG, &sighandler_shutdown);
+ shc_gterm = GNUNET_SIGNAL_handler_install (GNUNET_TERM_SIG,
+ &sighandler_shutdown);
#endif
#ifndef MINGW
- shc_pipe = GNUNET_SIGNAL_handler_install (SIGPIPE, &sighandler_pipe);
- shc_quit = GNUNET_SIGNAL_handler_install (SIGQUIT, &sighandler_shutdown);
- shc_hup = GNUNET_SIGNAL_handler_install (SIGHUP, &sighandler_shutdown);
+ shc_pipe = GNUNET_SIGNAL_handler_install (SIGPIPE,
+ &sighandler_pipe);
+ shc_quit = GNUNET_SIGNAL_handler_install (SIGQUIT,
+ &sighandler_shutdown);
+ shc_hup = GNUNET_SIGNAL_handler_install (SIGHUP,
+ &sighandler_shutdown);
#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,
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)
"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);
+ dump_backtrace (t);
+ }
+ }
+ 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);
+ dump_backtrace (t);
+ }
+ }
+ }
+#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);
/**
- * Obtain the reason code for why the current task was
- * started. Will return the same value as
- * the `struct GNUNET_SCHEDULER_TaskContext`'s reason field.
+ * Obtain the task context, giving the reason why the current task was
+ * started.
*
- * @return reason(s) why the current task is run
+ * @return current tasks' scheduler context
*/
-enum GNUNET_SCHEDULER_Reason
-GNUNET_SCHEDULER_get_reason ()
+const struct GNUNET_SCHEDULER_TaskContext *
+GNUNET_SCHEDULER_get_task_context ()
{
GNUNET_assert (NULL != active_task);
- return active_task->reason;
+ return &tc;
}
enum GNUNET_SCHEDULER_Priority p;
void *ret;
- GNUNET_assert (NULL != active_task);
+ GNUNET_assert ( (NULL != active_task) ||
+ (GNUNET_NO == task->lifeness) );
if (! task->in_ready_list)
{
if ( (-1 == task->read_fd) &&
(NULL == task->read_set) &&
(NULL == task->write_set) )
{
- GNUNET_CONTAINER_DLL_remove (pending_timeout_head,
- pending_timeout_tail,
- task);
+ if (GNUNET_YES == task->on_shutdown)
+ GNUNET_CONTAINER_DLL_remove (shutdown_head,
+ shutdown_tail,
+ task);
+ else
+ GNUNET_CONTAINER_DLL_remove (pending_timeout_head,
+ pending_timeout_tail,
+ task);
if (task == pending_timeout_last)
pending_timeout_last = NULL;
}
}
+/**
+ * Initialize backtrace data for task @a t
+ *
+ * @param t task to initialize
+ */
+static void
+init_backtrace (struct GNUNET_SCHEDULER_Task *t)
+{
+#if EXECINFO
+ void *backtrace_array[MAX_TRACE_DEPTH];
+
+ t->num_backtrace_strings
+ = backtrace (backtrace_array, MAX_TRACE_DEPTH);
+ t->backtrace_strings =
+ backtrace_symbols (backtrace_array,
+ t->num_backtrace_strings);
+ dump_backtrace (t);
+#endif
+}
+
+
/**
* Continue the current execution with the given function. This is
* similar to the other "add" functions except that there is no delay
* @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;
-#if EXECINFO
- void *backtrace_array[50];
-#endif
-
GNUNET_assert (NULL != task);
GNUNET_assert ((NULL != active_task) ||
(GNUNET_SCHEDULER_REASON_STARTUP == reason));
t = GNUNET_new (struct GNUNET_SCHEDULER_Task);
-#if EXECINFO
- t->num_backtrace_strings = backtrace (backtrace_array, 50);
- t->backtrace_strings =
- backtrace_symbols (backtrace_array, t->num_backtrace_strings);
-#endif
t->read_fd = -1;
t->write_fd = -1;
t->callback = task;
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Adding continuation task %p\n",
t);
+ init_backtrace (t);
queue_ready_task (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.
*
- * @param delay when should this operation time out? Use
- * #GNUNET_TIME_UNIT_FOREVER_REL for "on shutdown"
+ * @param delay when should this operation time out?
* @param priority priority to use for the task
* @param task main function of the task
* @param task_cls closure of @a task
struct GNUNET_SCHEDULER_Task *pos;
struct GNUNET_SCHEDULER_Task *prev;
-#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
t->read_fd = -1;
t->write_fd = -1;
#if PROFILE_DELAYS
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
+ init_backtrace (t);
return t;
}
* will be scheduled for execution once the delay has expired. It
* will be run with the DEFAULT priority.
*
- * @param delay when should this operation time out? Use
- * GNUNET_TIME_UNIT_FOREVER_REL for "on shutdown"
+ * @param delay when should this operation time out?
* @param task main function of the task
- * @param task_cls closure of task
+ * @param task_cls closure of @a task
* @return unique task identifier for the job
- * only valid until "task" is started!
+ * only valid until @a task is started!
*/
struct GNUNET_SCHEDULER_Task *
GNUNET_SCHEDULER_add_delayed (struct GNUNET_TIME_Relative delay,
- GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
+ GNUNET_SCHEDULER_TaskCallback task,
+ void *task_cls)
{
return GNUNET_SCHEDULER_add_delayed_with_priority (delay,
GNUNET_SCHEDULER_PRIORITY_DEFAULT,
* @param task main function of the task
* @param task_cls closure of @a task
* @return unique task identifier for the job
- * only valid until "task" is started!
+ * only valid until @a task is started!
+ */
+struct GNUNET_SCHEDULER_Task *
+GNUNET_SCHEDULER_add_now (GNUNET_SCHEDULER_TaskCallback task,
+ void *task_cls)
+{
+ return GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_ZERO,
+ task,
+ task_cls);
+}
+
+
+/**
+ * Schedule a new task to be run on shutdown, that is when a CTRL-C
+ * signal is received, or when #GNUNET_SCHEDULER_shutdown() is being
+ * invoked.
+ *
+ * @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 (GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
+GNUNET_SCHEDULER_add_shutdown (GNUNET_SCHEDULER_TaskCallback task,
+ void *task_cls)
{
- return GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_ZERO, task, task_cls);
+ struct GNUNET_SCHEDULER_Task *t;
+
+ GNUNET_assert (NULL != active_task);
+ GNUNET_assert (NULL != task);
+ t = GNUNET_new (struct GNUNET_SCHEDULER_Task);
+ t->callback = task;
+ t->callback_cls = task_cls;
+ t->read_fd = -1;
+ t->write_fd = -1;
+#if PROFILE_DELAYS
+ t->start_time = GNUNET_TIME_absolute_get ();
+#endif
+ t->timeout = GNUNET_TIME_UNIT_FOREVER_ABS;
+ t->priority = GNUNET_SCHEDULER_PRIORITY_SHUTDOWN;
+ t->on_shutdown = GNUNET_YES;
+ t->lifeness = GNUNET_YES;
+ GNUNET_CONTAINER_DLL_insert (shutdown_head,
+ shutdown_tail,
+ t);
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Adding task: %p\n",
+ t);
+ init_backtrace (t);
+ return t;
}
* (prerequisite-run)
* && (delay-ready
* || any-rs-ready
- * || any-ws-ready
- * || shutdown-active )
+ * || any-ws-ready)
* </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 delay how long should we wait?
* @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)
{
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)
{
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
+ init_backtrace (t);
GNUNET_assert (0);
}
}
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
+ init_backtrace (t);
GNUNET_assert (0);
}
}
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
+ init_backtrace (t);
return t;
}
#endif
* scheduled for execution once either the delay has expired or the
* socket operation is ready. It will be run with the DEFAULT priority.
*
- * @param delay when should this operation time out? Use
- * #GNUNET_TIME_UNIT_FOREVER_REL for "on shutdown"
+ * @param delay when should this operation time out?
* @param rfd read file-descriptor
* @param task main function of the task
* @param task_cls closure of @a task
* either the delay has expired or the socket operation is ready. It
* will be run with the DEFAULT priority.
*
- * @param delay when should this operation time out? Use
- * #GNUNET_TIME_UNIT_FOREVER_REL for "on shutdown"
+ * @param delay when should this operation time out?
* @param priority priority to use for the task
* @param rfd read file-descriptor
* @param task main function of the task
* socket operation is ready. It will be run with the priority of
* the calling task.
*
- * @param delay when should this operation time out? Use
- * #GNUNET_TIME_UNIT_FOREVER_REL for "on shutdown"
+ * @param delay when should this operation time out?
* @param wfd write file-descriptor
* @param task main function of the task
* @param task_cls closure of @a task
* scheduled for execution once either the delay has expired or the
* socket operation is ready.
*
- * @param delay when should this operation time out? Use
- * #GNUNET_TIME_UNIT_FOREVER_REL for "on shutdown"
+ * @param delay when should this operation time out?
* @param priority priority of the task
* @param fd file-descriptor
* @param on_read whether to poll the file-descriptor for readability
* scheduled for execution once either the delay has expired or the
* socket operation is ready. It will be run with the DEFAULT priority.
*
- * @param delay when should this operation time out? Use
- * #GNUNET_TIME_UNIT_FOREVER_REL for "on shutdown"
+ * @param delay when should this operation time out?
* @param rfd read file-descriptor
* @param task main function of the task
* @param task_cls closure of @a task
* scheduled for execution once either the delay has expired or the
* socket operation is ready. It will be run with the DEFAULT priority.
*
- * @param delay when should this operation time out? Use
- * #GNUNET_TIME_UNIT_FOREVER_REL for "on shutdown"
+ * @param delay when should this operation time out?
* @param wfd write file-descriptor
* @param task main function of the task
* @param task_cls closure of @a task
* scheduled for execution once either the delay has expired or the
* socket operation is ready.
*
- * @param delay when should this operation time out? Use
- * #GNUNET_TIME_UNIT_FOREVER_REL for "on shutdown"
+ * @param delay when should this operation time out?
* @param priority priority of the task
* @param fd file-descriptor
* @param on_read whether to poll the file-descriptor for readability
* (prerequisite-run)
* && (delay-ready
* || any-rs-ready
- * || any-ws-ready
- * || (shutdown-active && run-on-shutdown) )
+ * || any-ws-ready) )
* </code>
*
* @param prio how important is this task?
- * @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 delay how long should we wait?
* @param rs set of file descriptors we want to read (can be NULL)
* @param ws set of file descriptors we want to write (can be NULL)
* @param task main function of the task
void *task_cls)
{
struct GNUNET_SCHEDULER_Task *t;
-#if EXECINFO
- void *backtrace_array[MAX_TRACE_DEPTH];
-#endif
if ( (NULL == rs) &&
(NULL == ws) )
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
t->read_fd = -1;
t->write_fd = -1;
if (NULL != rs)
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Adding task %p\n",
t);
-#if EXECINFO
- 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
+ init_backtrace (t);
return t;
}