]> Devoid-pointer.net GitWeb - KLGD.git/commitdiff
- Allow for no init function in plugin
authorMichal Malý <madcatxster@devoid-pointer.net>
Sun, 27 Jul 2014 13:56:25 +0000 (15:56 +0200)
committerMichal Malý <madcatxster@devoid-pointer.net>
Sun, 27 Jul 2014 13:56:25 +0000 (15:56 +0200)
- No extra data to plugin init (use private instead)
- Allow for synchronous send_command_stream() callback
- Move the module-speific macros out of the header file

klgd.c
klgd.h

diff --git a/klgd.c b/klgd.c
index c1c84caf5e43b008321289a6792079d7131525b2..059409e27f0151a4914ce57aa02ecec51773712a 100644 (file)
--- a/klgd.c
+++ b/klgd.c
@@ -6,6 +6,10 @@
 #include <linux/workqueue.h>
 #include "klgd.h"
 
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Michal \"MadCatX\" Maly");
+MODULE_DESCRIPTION("Pluginable framework of helper functions to handle gaming devices");
+
 struct klgd_main_private {
        struct delayed_work work;
        bool can_send_commands;
@@ -18,10 +22,11 @@ struct klgd_main_private {
        struct mutex stream_mlock;
        struct workqueue_struct *wq;
 
-       int (*send_command_stream)(void *dev_ctx, struct klgd_command_stream *stream);
+       enum klgd_send_status (*send_command_stream)(void *dev_ctx, struct klgd_command_stream *stream);
 };
 
 static void klgd_free_stream(struct klgd_command_stream *s);
+static void klgd_notify_commands_sent_internal(struct klgd_main_private *priv);
 static void klgd_schedule_update(struct klgd_main *ctx);
 
 static bool klgd_append_stream(struct klgd_command_stream *target, struct klgd_command_stream *source)
@@ -47,14 +52,14 @@ static bool klgd_append_stream(struct klgd_command_stream *target, struct klgd_c
 /**
  * Called with stream_mlock held
  */
-static void klgd_build_command_stream(struct klgd_main_private *priv)
+static enum klgd_send_status klgd_build_command_stream(struct klgd_main_private *priv)
 {
        const unsigned long now = jiffies;
        size_t idx;
 
        struct klgd_command_stream *s = kzalloc(sizeof(struct klgd_command_stream), GFP_KERNEL);
        if (!s)
-               return; /* FIXME: Try to do an update later when some memory might be available */
+               return KLGD_SS_DONE; /* FIXME: Try to do an update later when some memory might be available */
 
        for (idx = 0; idx < priv->plugin_count; idx++) {
                struct klgd_plugin *plugin = priv->plugins[idx];
@@ -62,15 +67,16 @@ static void klgd_build_command_stream(struct klgd_main_private *priv)
                /* FIXME: Same as above */
                if (!klgd_append_stream(s, ss)) {
                        klgd_free_stream(s);
-                       return;
+                       return KLGD_SS_DONE;
                }
        }
 
        if (s->count) {
                priv->can_send_commands = false;
                priv->last_stream = s;
-               priv->send_command_stream(priv->device_context, s);
+               return priv->send_command_stream(priv->device_context, s);
        }
+       return KLGD_SS_DONE;
 }
 
 static void klgd_delayed_work(struct work_struct *w)
@@ -81,13 +87,18 @@ static void klgd_delayed_work(struct work_struct *w)
 
        mutex_lock(&priv->stream_mlock);
        if (priv->can_send_commands) {
+               int ret;
+
                pr_debug("Timer fired, can send commands now\n");
-               klgd_build_command_stream(priv);
+               ret = klgd_build_command_stream(priv);
+               if (ret == KLGD_SS_DONE)
+                       klgd_notify_commands_sent_internal(priv);
        } else {
                pr_debug("Timer fired, last stream of commands is still being processed\n");
                priv->send_asap++;
        }
 
+
        klgd_schedule_update(m);
        mutex_unlock(&priv->stream_mlock);
 }
@@ -113,6 +124,7 @@ void klgd_deinit(struct klgd_main *ctx)
        cancel_delayed_work(&priv->work);
        flush_workqueue(priv->wq);
        destroy_workqueue(priv->wq);
+       printk(KERN_NOTICE "KLGD deinit, workqueue terminated\n");
 
        for (idx = 0; idx < priv->plugin_count; idx++) {
                struct klgd_plugin *plugin = priv->plugins[idx];
@@ -120,16 +132,16 @@ void klgd_deinit(struct klgd_main *ctx)
                if (!plugin)
                        continue;
 
-               plugin->deinit(plugin);
+               if (plugin->deinit)
+                       plugin->deinit(plugin);
                kfree(plugin);
        }
        kfree(priv->plugins);
 
        kfree(priv);
-       kfree(ctx);
 }
 
-int klgd_init(struct klgd_main *ctx, void *dev_ctx, int (*callback)(void *, struct klgd_command_stream *), const size_t plugin_count)
+int klgd_init(struct klgd_main *ctx, void *dev_ctx, enum klgd_send_status (*callback)(void *, struct klgd_command_stream *), const size_t plugin_count)
 {
        struct klgd_main_private *priv = ctx->private;
        int ret;
@@ -180,6 +192,15 @@ void klgd_notify_commands_sent(struct klgd_main *ctx)
        struct klgd_main_private *priv = ctx->private;
 
        mutex_lock(&priv->stream_mlock);
+       klgd_notify_commands_sent_internal(priv);               
+       mutex_unlock(&priv->stream_mlock);
+}
+
+/**
+ * Called with stream_lock held
+ */
+static void klgd_notify_commands_sent_internal(struct klgd_main_private *priv)
+{
        kfree(priv->last_stream);
 
        if (priv->send_asap) {
@@ -190,7 +211,6 @@ void klgd_notify_commands_sent(struct klgd_main *ctx)
                pr_debug("Command stream processed, wait for timer\n");
                priv->can_send_commands = true;
        }
-       mutex_unlock(&priv->stream_mlock);
 }
 
 int klgd_post_event(struct klgd_main *ctx, size_t idx, void *data)
@@ -225,6 +245,9 @@ int klgd_register_plugin(struct klgd_main *ctx, size_t idx, struct klgd_plugin *
                return -ENOMEM;
 
        priv->plugins[idx] = plugin;
+       if (plugin->init)
+             plugin->init(plugin);
+
        return 0;
 }
 
diff --git a/klgd.h b/klgd.h
index a5161650d1f3d61f2ce54983674239b0b8cf1496..b829affa9b92cf8c61e3dfeceb7a6ac79b029faf 100644 (file)
--- a/klgd.h
+++ b/klgd.h
@@ -1,6 +1,8 @@
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Michal \"MadCatX\" Maly");
-MODULE_DESCRIPTION("Pluginable framework of helper functions to handle gaming devices");
+enum klgd_send_status {
+       KLGD_SS_RUNNING,
+       KLGD_SS_DONE,
+       KLGD_SS_FAILED
+};
 
 struct klgd_command {
        const char *bytes;
@@ -22,13 +24,13 @@ struct klgd_plugin {
        void (*deinit)(struct klgd_plugin *ctx);
        struct klgd_command_stream *(*get_commands)(struct klgd_plugin *ctx, const unsigned long now);
        bool (*get_update_time)(struct klgd_plugin *ctx, const unsigned long now, unsigned long *t);
-       int (*init)(struct klgd_plugin *ctx, void *data);
+       int (*init)(struct klgd_plugin *ctx);
        bool (*needs_attention)(struct klgd_plugin *ctx);
        int (*post_event)(struct klgd_plugin *ctx, void *data);
 };
 
 void klgd_deinit(struct klgd_main *ctx);
-int klgd_init(struct klgd_main *ctx, void *dev_ctx, int (*callback)(void *, struct klgd_command_stream *), const unsigned long plugin_count);
+int klgd_init(struct klgd_main *ctx, void *dev_ctx, enum klgd_send_status (*callback)(void *, struct klgd_command_stream *), const unsigned long plugin_count);
 void klgd_notify_commands_sent(struct klgd_main *ctx);
 int klgd_post_event(struct klgd_main *ctx, const size_t idx, void *data);
 int klgd_register_plugin(struct klgd_main *ctx, const size_t idx, struct klgd_plugin *plugin);