text: use new shl-registry objects
authorDavid Herrmann <dh.herrmann@googlemail.com>
Sun, 30 Dec 2012 15:21:27 +0000 (16:21 +0100)
committerDavid Herrmann <dh.herrmann@googlemail.com>
Sun, 30 Dec 2012 15:21:27 +0000 (16:21 +0100)
Instead of implementing our own thread-safe backend-storage, we now use
the generic shl-registry object.

Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
Makefile.am
src/text.c
src/text.h

index db2eeae..1dd0089 100644 (file)
@@ -370,6 +370,7 @@ kmscon_SOURCES = \
        $(SHL_RING) \
        $(SHL_TIMER) \
        $(SHL_HOOK) \
+       $(SHL_REGISTER) \
        src/conf.h \
        src/conf.c \
        src/log.h \
index d14ce2f..055f498 100644 (file)
 #include <string.h>
 #include "log.h"
 #include "shl_dlist.h"
+#include "shl_register.h"
 #include "text.h"
 #include "uterm.h"
 
 #define LOG_SUBSYSTEM "text"
 
-struct text_backend {
-       struct shl_dlist list;
-       const struct kmscon_text_ops *ops;
-};
-
-static pthread_mutex_t text_mutex = PTHREAD_MUTEX_INITIALIZER;
-static struct shl_dlist text__list = SHL_DLIST_INIT(text__list);
-
-static void text_lock()
-{
-       pthread_mutex_lock(&text_mutex);
-}
-
-static void text_unlock()
-{
-       pthread_mutex_unlock(&text_mutex);
-}
+static struct shl_register text_reg = SHL_REGISTER_INIT(text_reg);
 
 /**
  * kmscon_text_register:
@@ -76,43 +61,21 @@ static void text_unlock()
  */
 int kmscon_text_register(const struct kmscon_text_ops *ops)
 {
-       struct shl_dlist *iter;
-       struct text_backend *be;
        int ret;
 
-       if (!ops || !ops->name)
+       if (!ops)
                return -EINVAL;
 
        log_debug("register text backend %s", ops->name);
 
-       text_lock();
-
-       shl_dlist_for_each(iter, &text__list) {
-               be = shl_dlist_entry(iter, struct text_backend, list);
-               if (!strcmp(be->ops->name, ops->name)) {
-                       log_error("registering already available backend %s",
-                                 ops->name);
-                       ret = -EALREADY;
-                       goto out_unlock;
-               }
-       }
-
-       be = malloc(sizeof(*be));
-       if (!be) {
-               log_error("cannot allocate memory for backend");
-               ret = -ENOMEM;
-               goto out_unlock;
+       ret = shl_register_add(&text_reg, ops->name, (void*)ops);
+       if (ret) {
+               log_error("cannot register text backend %s: %d", ops->name,
+                         ret);
+               return ret;
        }
 
-       memset(be, 0, sizeof(*be));
-       be->ops = ops;
-       shl_dlist_link(&text__list, &be->list);
-
-       ret = 0;
-
-out_unlock:
-       text_unlock();
-       return ret;
+       return 0;
 }
 
 /**
@@ -120,39 +83,48 @@ out_unlock:
  * @name: Name of backend
  *
  * This unregisters the text-backend that is registered with name @name. If
- * @name is not found, a warning is printed but nothing else is done.
+ * @name is not found, nothing is done.
  */
 void kmscon_text_unregister(const char *name)
 {
-       struct shl_dlist *iter;
-       struct text_backend *be;
-
-       if (!name)
-               return;
-
        log_debug("unregister backend %s", name);
+       shl_register_remove(&text_reg, name);
+}
+
+static int new_text(struct kmscon_text *text, const char *backend)
+{
+       struct shl_register_record *record;
+       const char *name = backend ? backend : "<default>";
+       int ret;
 
-       text_lock();
+       memset(text, 0, sizeof(*text));
+       text->ref = 1;
 
-       shl_dlist_for_each(iter, &text__list) {
-               be = shl_dlist_entry(iter, struct text_backend, list);
-               if (strcmp(name, be->ops->name))
-                       continue;
+       if (backend)
+               record = shl_register_find(&text_reg, backend);
+       else
+               record = shl_register_first(&text_reg);
 
-               shl_dlist_unlink(&be->list);
-               break;
+       if (!record) {
+               log_error("requested backend '%s' not found", name);
+               return -ENOENT;
        }
 
-       if (iter == &text__list)
-               be = NULL;
+       text->record = record;
+       text->ops = record->data;
 
-       text_unlock();
+       if (text->ops->init)
+               ret = text->ops->init(text);
+       else
+               ret = 0;
 
-       if (!be) {
-               log_error("cannot unregister backend %s: not found", name);
-       } else {
-               free(be);
+       if (ret) {
+               log_warning("backend %s cannot create renderer", name);
+               shl_register_record_unref(record);
+               return ret;
        }
+
+       return 0;
 }
 
 /**
@@ -162,94 +134,34 @@ void kmscon_text_unregister(const char *name)
  *
  * Returns: 0 on success, error code on failure
  */
-int kmscon_text_new(struct kmscon_text **out,
-                   const char *backend)
+int kmscon_text_new(struct kmscon_text **out, const char *backend)
 {
        struct kmscon_text *text;
-       struct shl_dlist *iter;
-       struct text_backend *be, *def;
        int ret;
 
        if (!out)
                return -EINVAL;
 
-       text_lock();
-
-       if (shl_dlist_empty(&text__list)) {
-               log_error("no text backend available");
-               ret = -EFAULT;
-       } else {
-               ret = 0;
-               def = shl_dlist_entry(text__list.prev,
-                                        struct text_backend,
-                                        list);
-               if (!backend) {
-                       be = def;
-               } else {
-                       shl_dlist_for_each(iter, &text__list) {
-                               be = shl_dlist_entry(iter,
-                                                       struct text_backend,
-                                                       list);
-                               if (!strcmp(backend, be->ops->name))
-                                       break;
-                       }
-                       if (iter == &text__list) {
-                               log_warning("requested backend %s not found",
-                                           backend);
-                               be = def;
-                       }
-               }
-       }
-
-       if (ret)
-               goto out_unlock;
-
        text = malloc(sizeof(*text));
        if (!text) {
                log_error("cannot allocate memory for new text-renderer");
-               ret = -ENOMEM;
-               goto out_unlock;
+               return -ENOMEM;
        }
-       memset(text, 0, sizeof(*text));
-       text->ref = 1;
-       text->ops = be->ops;
-
-       if (text->ops->init)
-               ret = text->ops->init(text);
-       else
-               ret = 0;
 
+       ret = new_text(text, backend);
        if (ret) {
-               if (be == def) {
-                       log_error("default backend %s cannot create renderer",
-                                 text->ops->name);
-                       goto err_free;
-               }
-
-               log_warning("backend %s cannot create renderer; trying default backend %s",
-                           be->ops->name, def->ops->name);
-
-               memset(text, 0, sizeof(*text));
-               text->ref = 1;
-               text->ops = def->ops;
-
-               ret = text->ops->init(text);
-               if (ret) {
-                       log_error("default backend %s cannot create renderer",
-                                 text->ops->name);
+               if (backend)
+                       ret = new_text(text, NULL);
+               if (ret)
                        goto err_free;
-               }
        }
 
        log_debug("using: be: %s", text->ops->name);
        *out = text;
-       ret = 0;
-       goto out_unlock;
+       return 0;
 
 err_free:
        free(text);
-out_unlock:
-       text_unlock();
        return ret;
 }
 
@@ -282,13 +194,10 @@ void kmscon_text_unref(struct kmscon_text *text)
        log_debug("freeing text renderer");
        kmscon_text_unset(text);
 
-       text_lock();
-
        if (text->ops->destroy)
                text->ops->destroy(text);
+       shl_register_record_unref(text->record);
        free(text);
-
-       text_unlock();
 }
 
 /**
index 85b4a95..f099a60 100644 (file)
@@ -121,6 +121,7 @@ struct kmscon_text_ops;
 
 struct kmscon_text {
        unsigned long ref;
+       struct shl_register_record *record;
        const struct kmscon_text_ops *ops;
        void *data;