[evince/wip/bug654832: 7/16] libdocument: Store the EvBackendInfo as object data on the document



commit 73ca8dd3b49f33b94ec053b1be3b3bb57922deee
Author: Christian Persch <chpe gnome org>
Date:   Sat Mar 27 15:45:59 2010 +0100

    libdocument: Store the EvBackendInfo as object data on the document

 libdocument/ev-backend-info.c     |   29 +++++++++++++++++++++++++----
 libdocument/ev-backend-info.h     |   14 +++++++++-----
 libdocument/ev-document-factory.c |   27 ++++++++++++---------------
 3 files changed, 46 insertions(+), 24 deletions(-)
---
diff --git a/libdocument/ev-backend-info.c b/libdocument/ev-backend-info.c
index 629c882..08daf2e 100644
--- a/libdocument/ev-backend-info.c
+++ b/libdocument/ev-backend-info.c
@@ -28,18 +28,38 @@
  * _ev_backend_info_free:
  * @info:
  *
- * Frees @info
+ * Increases refcount of @info by 1.
+ */
+EvBackendInfo *
+_ev_backend_info_ref (EvBackendInfo *info)
+{
+        g_return_val_if_fail (info != NULL, NULL);
+        g_return_val_if_fail (info->ref_count >= 1, NULL);
+
+        g_atomic_int_inc (&info->ref_count);
+        return info;
+}
+
+/*
+ * _ev_backend_info_free:
+ * @info:
+ *
+ * Decreases refcount of @info by 1, and frees @info if the refcount reaches 0.
  */
 void
-_ev_backend_info_free (EvBackendInfo *info)
+_ev_backend_info_unref (EvBackendInfo *info)
 {
         if (info == NULL)
                 return;
 
+        g_return_if_fail (info->ref_count >= 1);
+
+        if (!g_atomic_int_dec_and_test (&info->ref_count))
+                return;
+
 	g_free (info->module_name);
 	g_free (info->type_desc);
 	g_strfreev (info->mime_types);
-        /* Leak info->module */
 	g_slice_free (EvBackendInfo, info);
 }
 
@@ -64,6 +84,7 @@ _ev_backend_info_new_from_file (const char *file,
                 goto err;
 
 	info = g_slice_new0 (EvBackendInfo);
+        info->ref_count = 1;
 
 	info->module_name = g_key_file_get_string (backend_file, EV_BACKENDS_GROUP,
 						   "Module", error);
@@ -89,7 +110,7 @@ _ev_backend_info_new_from_file (const char *file,
 
     err:
         g_key_file_free (backend_file);
-        _ev_backend_info_free (info);
+        _ev_backend_info_unref (info);
         return NULL;
 }
 
diff --git a/libdocument/ev-backend-info.h b/libdocument/ev-backend-info.h
index 14c0895..9b7ef49 100644
--- a/libdocument/ev-backend-info.h
+++ b/libdocument/ev-backend-info.h
@@ -37,17 +37,21 @@ struct _EvBackendInfo {
         gchar       *type_desc;
         gchar      **mime_types;
 
+        volatile int ref_count;
+
 	gchar       *module_name;
-	GTypeModule *module;
+        GTypeModule *module;
 	gboolean     resident;
 };
 
-void            _ev_backend_info_free           (EvBackendInfo *info);
+EvBackendInfo *_ev_backend_info_ref           (EvBackendInfo *info);
+
+void           _ev_backend_info_unref         (EvBackendInfo *info);
 
-EvBackendInfo  *_ev_backend_info_new_from_file  (const char *file,
-                                                 GError **error);
+EvBackendInfo *_ev_backend_info_new_from_file (const char *file,
+                                               GError **error);
 
-GList          *_ev_backend_info_load_from_dir  (const char *path);
+GList         *_ev_backend_info_load_from_dir (const char *path);
 
 G_END_DECLS
 
diff --git a/libdocument/ev-document-factory.c b/libdocument/ev-document-factory.c
index 5be8d81..6b26bcb 100644
--- a/libdocument/ev-document-factory.c
+++ b/libdocument/ev-document-factory.c
@@ -32,11 +32,14 @@
 #include "ev-backend-info.h"
 #include "ev-document-factory.h"
 #include "ev-file-helpers.h"
+#include "ev-module.h"
 
 #include "ev-backends-manager.h"
 
 /* Backends manager */
 
+#define BACKEND_DATA_KEY "ev-backend-info"
+
 static GList *ev_backends_list = NULL;
 static gchar *ev_backends_dir = NULL;
 
@@ -62,22 +65,12 @@ get_backend_info_for_mime_type (const gchar *mime_type)
 static EvBackendInfo *
 get_backend_info_for_document (EvDocument *document)
 {
-        GList *l;
-
-        for (l = ev_backends_list; l; l = l->next) {
-                EvBackendInfo *info = (EvBackendInfo *) l->data;
-                GType type;
-
-                if (!info->module)
-                        continue;
-
-                type = _ev_module_get_object_type (EV_MODULE (info->module));
+        EvBackendInfo *info;
 
-                if (G_TYPE_CHECK_INSTANCE_TYPE (document, type))
-                        return info;
-        }
+        info = g_object_get_data (G_OBJECT (document), BACKEND_DATA_KEY);
 
-        return NULL;
+        g_warn_if_fail (info != NULL);
+        return info;
 }
 
 EvDocument *
@@ -132,6 +125,10 @@ ev_document_factory_new_document_for_mime_type (const gchar *mime_type,
         document = EV_DOCUMENT (_ev_module_new_object (EV_MODULE (info->module)));
         g_type_module_unuse (info->module);
 
+        g_object_set_data_full (G_OBJECT (document), BACKEND_DATA_KEY, 
+                                _ev_backend_info_ref (info),
+                                (GDestroyNotify) _ev_backend_info_unref);
+
         return document;
 }
 
@@ -247,7 +244,7 @@ _ev_document_factory_init (void)
 void
 _ev_document_factory_shutdown (void)
 {
-	g_list_foreach (ev_backends_list, (GFunc) _ev_backend_info_free, NULL);
+	g_list_foreach (ev_backends_list, (GFunc) _ev_backend_info_unref, NULL);
 	g_list_free (ev_backends_list);
 	ev_backends_list = NULL;
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]