trigger: replace trigger_init() with static runqueue initialization
[project/procd.git] / service / trigger.c
index 41fb55dc4c5288f65faf082c4075c6cd72c1f380..55d07e4dfa9b1611eb90b540befc32513d31656e 100644 (file)
@@ -16,9 +16,6 @@
 #include <sys/socket.h>
 #include <sys/types.h>
 
-#include <linux/types.h>
-#include <linux/netlink.h>
-
 #include <libubox/blobmsg_json.h>
 #include <libubox/json_script.h>
 #include <libubox/runqueue.h>
@@ -65,7 +62,7 @@ struct job {
 };
 
 static LIST_HEAD(triggers);
-static struct runqueue q;
+static RUNQUEUE(q, 1);
 
 static const char* rule_handle_var(struct json_script_ctx *ctx, const char *name, struct blob_attr *vars)
 {
@@ -77,6 +74,9 @@ rule_load_script(struct json_script_ctx *ctx, const char *name)
 {
        struct trigger *t = container_of(ctx, struct trigger, jctx);
 
+       if (strcmp(name, t->type) != 0)
+               return NULL;
+
        return json_script_file_from_blobmsg(t->type, t->rule, blob_pad_len(t->rule));
 }
 
@@ -88,13 +88,21 @@ static void q_job_run(struct runqueue *q, struct runqueue_task *t)
        j->cmd->handler(j, j->exec, j->env);
 }
 
+static void trigger_free(struct trigger *t)
+{
+       json_script_free(&t->jctx);
+       uloop_timeout_cancel(&t->delay);
+       free(t->data);
+       list_del(&t->list);
+       free(t);
+}
+
 static void q_job_complete(struct runqueue *q, struct runqueue_task *p)
 {
        struct job *j = container_of(p, struct job, proc.task);
 
        if (j->trigger->remove) {
-               list_del(&j->trigger->list);
-               free(j->trigger);
+               trigger_free(j->trigger);
        } else {
                j->trigger->pending = 0;
        }
@@ -209,16 +217,13 @@ static void rule_handle_error(struct json_script_ctx *ctx, const char *msg,
        free(s);
 }
 
-static void q_empty(struct runqueue *q)
-{
-}
-
 static void trigger_delay_cb(struct uloop_timeout *tout)
 {
        struct trigger *t = container_of(tout, struct trigger, delay);
 
-       json_script_run(&t->jctx, "foo", t->data);
+       json_script_run(&t->jctx, t->type, t->data);
        free(t->data);
+       t->data = NULL;
 }
 
 static struct trigger* _trigger_add(char *type, struct blob_attr *rule, int timeout, void *id)
@@ -302,33 +307,34 @@ void trigger_del(void *id)
                        t->remove = 1;
                        continue;
                }
-               list_del(&t->list);
-               free(t);
+
+               trigger_free(t);
        }
 }
 
-void trigger_init(void)
+static bool trigger_match(const char *event, const char *match)
 {
-       runqueue_init(&q);
-       q.empty_cb = q_empty;
-       q.max_running_tasks = 1;
+       char *wildcard = strstr(match, ".*");
+       if (wildcard)
+               return !strncmp(event, match, wildcard - match);
+       return !strcmp(event, match);
 }
 
-void trigger_event(char *type, struct blob_attr *data)
+void trigger_event(const char *type, struct blob_attr *data)
 {
        struct trigger *t;
 
        list_for_each_entry(t, &triggers, list) {
-               if (t->pending || t->remove)
+               if (t->remove)
                        continue;
-               if (!strcmp(t->type, type)) {
-                       if (t->timeout) {
-                               t->data = malloc(blob_pad_len(data));
-                               memcpy(t->data, data, blob_pad_len(data));
-                               uloop_timeout_set(&t->delay, t->timeout);
-                       } else {
-                               json_script_run(&t->jctx, "foo", data);
-                       }
+               if (!trigger_match(type, t->type))
+                       continue;
+               if (t->timeout) {
+                       free(t->data);
+                       t->data = blob_memdup(data);
+                       uloop_timeout_set(&t->delay, t->timeout);
+               } else {
+                       json_script_run(&t->jctx, t->type, data);
                }
        }
 }