sched: Introduce task_status().
authorAndre Noll <maan@systemlinux.org>
Tue, 31 Dec 2013 17:22:57 +0000 (17:22 +0000)
committerAndre Noll <maan@systemlinux.org>
Sun, 25 May 2014 13:39:01 +0000 (15:39 +0200)
Before struct task can be made private to sched.c we must eliminate
code which directly accesses the fields of this structure. The last
offender is ->error: in many places we check this field to detect
whether some task is in an error condition.

This patch provides a public accessor function, task_status(),
for this purpose. All users of ->error are modified to call this
function instead.

audiod.c
client.c
interactive.c
play.c
sched.c
sched.h
write.c

index 461efaf..ee13644 100644 (file)
--- a/audiod.c
+++ b/audiod.c
@@ -593,7 +593,7 @@ static bool receiver_running(void)
 
                if (!s->receiver_node)
                        continue;
-               if (s->receiver_node->task->error >= 0)
+               if (task_status(s->receiver_node->task) >= 0)
                        return true;
                if (ss1 == ss2)
                        return true;
@@ -620,7 +620,7 @@ struct btr_node *audiod_get_btr_root(void)
                struct timeval rstime;
                if (!s->receiver_node)
                        continue;
-               if (s->receiver_node->task->error < 0)
+               if (task_status(s->receiver_node->task) < 0)
                        continue;
                btr_get_node_start(s->receiver_node->btrn, &rstime);
                if (newest_slot >= 0 && tv_diff(&rstime, &newest_rstime, NULL) < 0)
@@ -1109,17 +1109,17 @@ static bool must_close_slot(int slot_num)
 
        if (s->format < 0)
                return false;
-       if (s->receiver_node && s->receiver_node->task->error >= 0)
+       if (s->receiver_node && task_status(s->receiver_node->task) >= 0)
                return false;
        for (i = 0; i < a->num_filters; i++)
-               if (s->fns && s->fns[i].task->error >= 0)
+               if (s->fns && task_status(s->fns[i].task) >= 0)
                        return false;
        if (a->num_writers > 0) {
                for (i = 0; i < a->num_writers; i++)
-                       if (s->wns && s->wns[i].task->error >= 0)
+                       if (s->wns && task_status(s->wns[i].task) >= 0)
                                return false;
        } else {
-               if (s->wns && s->wns[0].task->error >= 0)
+               if (s->wns && task_status(s->wns[0].task) >= 0)
                        return false;
        }
        return true;
@@ -1235,7 +1235,7 @@ static int status_post_select(struct sched *s, struct task *t)
        if (audiod_status == AUDIOD_OFF) {
                if (!st->ct)
                        goto out;
-               if (st->ct->task->error >= 0) {
+               if (task_status(st->ct->task) >= 0) {
                        task_notify(st->ct->task, E_AUDIOD_OFF);
                        goto out;
                }
index 88b1e93..5573d03 100644 (file)
--- a/client.c
+++ b/client.c
@@ -536,9 +536,10 @@ struct supervisor_task {
 static int supervisor_post_select(struct sched *s, struct task *t)
 {
        struct supervisor_task *svt = task_context(t);
+       int ret = task_status(ct->task);
 
-       if (ct->task->error < 0)
-               return ct->task->error;
+       if (ret < 0)
+               return ret;
        if (!svt->stdout_task_started && ct->status == CL_EXECUTING) {
                stdout_task_register(&sot, s);
                svt->stdout_task_started = true;
@@ -606,16 +607,19 @@ int main(int argc, char *argv[])
        }, &sched);
 
        ret = schedule(&sched);
-       if (ret >= 0 && ct->task->error < 0) {
-               switch (ct->task->error) {
-               /* these are not errors */
-               case -E_SERVER_CMD_SUCCESS:
-               case -E_EOF:
-               case -E_SERVER_EOF:
-               case -E_BTR_EOF:
-                       ret = 0;
-                       break;
-               default: ret = -E_SERVER_CMD_FAILURE;
+       if (ret >= 0) {
+               ret = task_status(ct->task);
+               if (ret < 0) {
+                       switch (ret) {
+                       /* these are not errors */
+                       case -E_SERVER_CMD_SUCCESS:
+                       case -E_EOF:
+                       case -E_SERVER_EOF:
+                       case -E_BTR_EOF:
+                               ret = 0;
+                               break;
+                       default: ret = -E_SERVER_CMD_FAILURE;
+                       }
                }
        }
        sched_shutdown(&sched);
index 6a1db53..c5cdf12 100644 (file)
@@ -52,7 +52,7 @@ static struct i9e_private i9e_private, *i9ep = &i9e_private;
  */
 int i9e_get_error(void)
 {
-       return i9ep->task->error;
+       return task_status(i9ep->task);
 }
 
 static bool is_prefix(const char *partial, const char *full, size_t len)
diff --git a/play.c b/play.c
index f4202d2..088a1bf 100644 (file)
--- a/play.c
+++ b/play.c
@@ -247,12 +247,12 @@ static int get_playback_error(struct play_task *pt)
 
        if (!pt->wn.task)
                return 0;
-       err = pt->wn.task->error;
+       err = task_status(pt->wn.task);
        if (err >= 0)
                return 0;
-       if (pt->fn.task->error >= 0)
+       if (task_status(pt->fn.task) >= 0)
                return 0;
-       if (pt->rn.task->error >= 0)
+       if (task_status(pt->rn.task) >= 0)
                return 0;
        if (err == -E_BTR_EOF || err == -E_RECV_EOF || err == -E_EOF
                        || err == -E_WRITE_COMMON_EOF)
diff --git a/sched.c b/sched.c
index 1b83b70..fb0d4d6 100644 (file)
--- a/sched.c
+++ b/sched.c
@@ -315,6 +315,25 @@ int task_get_notification(const struct task *t)
        return t->notification;
 }
 
+/**
+ * Return the status value of a task.
+ *
+ * \param t The task to get the status value from.
+ *
+ * \return Zero if task does not exist, one if task is running, negative error
+ * code if task has terminated.
+ */
+int task_status(const struct task *t)
+{
+       if (!t)
+               return 0;
+       if (t->dead)
+               return 0;
+       if (t->error >= 0)
+               return 1;
+       return t->error;
+}
+
 /**
  * Set the notification value of all tasks of a scheduler instance.
  *
diff --git a/sched.h b/sched.h
index db6ee7d..6a35f0e 100644 (file)
--- a/sched.h
+++ b/sched.h
@@ -103,6 +103,7 @@ char *get_task_list(struct sched *s);
 void task_notify(struct task *t, int err);
 void task_notify_all(struct sched *s, int err);
 int task_get_notification(const struct task *t);
+int task_status(const struct task *t);
 int task_reap(struct task **tptr);
 void sched_min_delay(struct sched *s);
 void sched_request_timeout(struct timeval *to, struct sched *s);
diff --git a/write.c b/write.c
index 15bbb4a..4407784 100644 (file)
--- a/write.c
+++ b/write.c
@@ -123,16 +123,17 @@ static int setup_and_schedule(void)
        s.default_timeout.tv_usec = 50000;
        ret = schedule(&s);
        if (ret >= 0) {
-               int j;
+               int j, ts;
                for (j = 0; j < i; j++) {
-                       struct task *t = wns[j].task;
-                       assert(t->error < 0);
-                       if (t->error != -E_WRITE_COMMON_EOF
-                                       && t->error != -E_BTR_EOF) {
-                               PARA_ERROR_LOG("%s: %s\n", t->status,
-                                       para_strerror(-t->error));
+                       struct writer_node *wn = wns + j;
+                       ts = task_status(wn->task);
+                       assert(ts < 0);
+                       if (ts != -E_WRITE_COMMON_EOF && ts != -E_BTR_EOF) {
+                               const char *name = writer_names[wn->writer_num];
+                               PARA_ERROR_LOG("%s: %s\n", name,
+                                       para_strerror(-ts));
                                if (ret >= 0)
-                                       ret = t->error;
+                                       ret = ts;
                        }
                }
        }