+ * Obtain the error status of a task and deallocate its resources.
+ *
+ * \param tptr Identifies the task to reap.
+ *
+ * This function is similar to wait(2) in that it returns information about a
+ * terminated task and allows to release the resources associated with the
+ * task. Until this function is called, the terminated task remains in a zombie
+ * state.
+ *
+ * \return If \a tptr is \p NULL, or \a *tptr is \p NULL, the function does
+ * nothing and returns zero. Otherwise, it is checked whether the task
+ * identified by \a tptr is still running. If it is, the function returns zero
+ * and again, no action is taken. Otherwise the (negative) error code of the
+ * terminated task is returned and \a *tptr is set to \p NULL. The task will
+ * then be removed removed from the scheduler task list.
+ *
+ * \sa \ref sched_shutdown(), wait(2).
+ */
+int task_reap(struct task **tptr)
+{
+ struct task *t;
+
+ if (!tptr)
+ return 0;
+ t = *tptr;
+ if (!t)
+ return 0;
+ if (!t->owned_by_sched)
+ return 0;
+ if (t->error >= 0)
+ return 0;
+ if (t->dead) /* will be freed in sched_post_select() */
+ return 0;
+ /*
+ * With list_for_each_entry_safe() it is only safe to remove the
+ * _current_ list item. Since we are being called from the loop in
+ * schedule() via some task's ->post_select() function, freeing the
+ * given task here would result in use-after-free bugs in schedule().
+ * So we only set t->dead which tells schedule() to free the task in
+ * the next iteration of its loop.
+ */
+ t->dead = true;
+ *tptr = NULL;
+ return t->error;
+}
+
+/**
+ * Deallocate all resources of all tasks of a scheduler instance.
+ *
+ * \param s The scheduler instance.
+ *
+ * This should only be called after \ref schedule() has returned.
+ */
+void sched_shutdown(struct sched *s)
+{
+ struct task *t, *tmp;
+
+ list_for_each_entry_safe(t, tmp, &s->task_list, node) {
+ if (t->error >= 0)
+ /* The task list should contain only terminated tasks. */
+ PARA_WARNING_LOG("shutting down running task %s\n",
+ t->status);
+ unlink_and_free_task(t);
+ }
+}
+
+/**
+ * Add a task to the scheduler. Deprecated.