Adds 2017 to copyrights
[src/app-framework-main.git] / src / afm-run.c
index 131f9cb..55b2daf 100644 (file)
@@ -1,5 +1,5 @@
 /*
- Copyright 2015, 2016 IoT.bzh
+ Copyright 2015, 2016, 2017 IoT.bzh
 
  author: José Bollo <jose.bollo@iot.bzh>
 
@@ -179,6 +179,61 @@ static void pgid_remove(struct apprun *runner)
 
 /****************** manages runners (by runid) **********************/
 
+/*
+ * Is a 'runner' alive?
+ */
+static inline int is_alive(struct apprun *runner)
+{
+       switch(runner->state) {
+       case as_terminating:
+       case as_terminated:
+               return 0;
+       default:
+               return 1;
+       }
+}
+
+/*
+ * Is a 'runner' dead?
+ */
+static inline int is_dead(struct apprun *runner)
+{
+       switch(runner->state) {
+       case as_terminating:
+       case as_terminated:
+               return 1;
+       default:
+               return 0;
+       }
+}
+
+/*
+ * Is a 'runner' running?
+ */
+static inline int is_running(struct apprun *runner)
+{
+       switch(runner->state) {
+       case as_starting:
+       case as_running:
+               return 1;
+       default:
+               return 0;
+       }
+}
+
+/*
+ * Is a 'runner' paused?
+ */
+static inline int is_paused(struct apprun *runner)
+{
+       switch(runner->state) {
+       case as_paused:
+               return 1;
+       default:
+               return 0;
+       }
+}
+
 /*
  * Get a runner by its 'runid'  (NULL if not found)
  */
@@ -192,6 +247,25 @@ static struct apprun *getrunner(int runid)
        return result;
 }
 
+/*
+ * Get first runner of 'appli' (NULL if not found)
+ */
+static struct apprun *getrunner_appli(json_object *appli)
+{
+       int i;
+       struct apprun *result;
+
+       for (i = 0 ; i < ROOT_RUNNERS_COUNT ; i++) {
+               result = runners_by_pgid[i];
+               while (result != NULL) {
+                       if (result->appli == appli)
+                               return result;
+                       result = result->next_by_pgid;
+               }
+       }
+       return NULL;
+}
+
 /*
  * Free an existing 'runner'
  */
@@ -315,7 +389,7 @@ static int killrunner(int runid, int sig, enum appstate tostate)
                errno = ENOENT;
                rc = -1;
        }
-       else if (runner->state != as_running && runner->state != as_paused) {
+       else if (is_dead(runner)) {
                errno = EINVAL;
                rc = -1;
        }
@@ -434,10 +508,7 @@ static json_object *mkstate(struct apprun *runner)
                goto error2;
 
        /* the pids */
-       switch(runner->state) {
-       case as_starting:
-       case as_running:
-       case as_paused:
+       if (is_alive(runner)) {
                pids = j_add_new_array(result, "pids");
                if (!pids)
                        goto error2;
@@ -445,9 +516,6 @@ static json_object *mkstate(struct apprun *runner)
                        goto error2;
                if (runner->pids[1] && !j_add_integer(pids, NULL, runner->pids[1]))
                        goto error2;
-               break;
-       default:
-               break;
        }
 
        /* the state */
@@ -496,12 +564,12 @@ error:
  * runner. This is made using json_object_get. Thus be aware
  * that further modifications to 'appli' might create errors.
  *
- * Returns 0 in case of success or -1 in case of error
+ * Returns the runid in case of success or -1 in case of error
  */
 int afm_run_start(struct json_object *appli, enum afm_launch_mode mode,
                                                        char **uri)
 {
-       static struct apprun *runner;
+       struct apprun *runner;
        struct afm_launch_desc desc;
        int rc;
        sigset_t saved, blocked;
@@ -543,6 +611,23 @@ int afm_run_start(struct json_object *appli, enum afm_launch_mode mode,
        return rc;
 }
 
+/*
+ * Returns the runid of a previously started application 'appli'
+ * or if none is running, starts the application described by 'appli'
+ * in local mode.
+ *
+ * A reference to 'appli' is kept during the live of the
+ * runner. This is made using json_object_get. Thus be aware
+ * that further modifications to 'appli' might create errors.
+ *
+ * Returns the runid in case of success or -1 in case of error
+ */
+int afm_run_once(struct json_object *appli)
+{
+       struct apprun *runner = getrunner_appli(appli);
+       return runner && is_alive(runner) ? runner->runid : afm_run_start(appli, mode_local, NULL);
+}
+
 /*
  * Terminates the runner of 'runid'
  *
@@ -593,8 +678,7 @@ struct json_object *afm_run_list()
        for (i = 0 ; i < ROOT_RUNNERS_COUNT ; i++) {
                runner = runners_by_runid[i];
                while (runner) {
-                       if (runner->state != as_terminating
-                                       && runner->state != as_terminated) {
+                       if (is_alive(runner)) {
                                /* adds the living runner */
                                obj = mkstate(runner);
                                if (obj == NULL)
@@ -624,8 +708,7 @@ error:
 struct json_object *afm_run_state(int runid)
 {
        struct apprun *runner = getrunner(runid);
-       if (runner == NULL || runner->state == as_terminating
-                               || runner->state == as_terminated) {
+       if (runner == NULL || is_dead(runner)) {
                errno = ENOENT;
                return NULL;
        }