[tracker] libtracker-db: Shut down properly thread data on thread destruction.



commit 64979fb3b8cfe1a8a382aa3323fac78f4a46fbf4
Author: Carlos Garnacho <carlosg gnome org>
Date:   Thu May 6 18:21:33 2010 +0200

    libtracker-db: Shut down properly thread data on thread destruction.
    
    At the time a thread is being destroyed, g_thread_self() is no longer reliable,
    nor any g_private_set() calls on further data our interface threads depend on
    (such as FTS).
    
    So, do not rely on GThread for removing from the interfaces hashtable, and
    attach the FTS data struct directly to the TrackerDBInterface so we can shut
    it down before closing the database (it also likes to do queries, which might
    not be finalized yet)

 src/libtracker-db/tracker-db-interface-sqlite.c |    7 ++++---
 src/libtracker-db/tracker-db-manager.c          |   13 ++++++++++++-
 src/libtracker-fts/tracker-fts.c                |   22 +++++++++++++++-------
 src/libtracker-fts/tracker-fts.h                |    5 +++--
 4 files changed, 34 insertions(+), 13 deletions(-)
---
diff --git a/src/libtracker-db/tracker-db-interface-sqlite.c b/src/libtracker-db/tracker-db-interface-sqlite.c
index 1f75d87..62bacb7 100644
--- a/src/libtracker-db/tracker-db-interface-sqlite.c
+++ b/src/libtracker-db/tracker-db-interface-sqlite.c
@@ -609,7 +609,8 @@ tracker_db_interface_sqlite_get_property (GObject    *object,
 }
 
 static void
-close_database (TrackerDBInterfaceSqlitePrivate *priv)
+close_database (GObject                         *object,
+                TrackerDBInterfaceSqlitePrivate *priv)
 {
 	gint rc;
 
@@ -636,7 +637,7 @@ tracker_db_interface_sqlite_fts_init (TrackerDBInterfaceSqlite *interface,
 
 	priv = TRACKER_DB_INTERFACE_SQLITE_GET_PRIVATE (interface);
 
-	tracker_fts_init (priv->db, create);
+	tracker_fts_init (priv->db, create, G_OBJECT (interface));
 	priv->fts_initialized = TRUE;
 }
 
@@ -647,7 +648,7 @@ tracker_db_interface_sqlite_finalize (GObject *object)
 
 	priv = TRACKER_DB_INTERFACE_SQLITE_GET_PRIVATE (object);
 
-	close_database (priv);
+	close_database (object, priv);
 
 	g_message ("Closed sqlite3 database:'%s'", priv->filename);
 
diff --git a/src/libtracker-db/tracker-db-manager.c b/src/libtracker-db/tracker-db-manager.c
index 51aa979..fb3ea94 100644
--- a/src/libtracker-db/tracker-db-manager.c
+++ b/src/libtracker-db/tracker-db-manager.c
@@ -633,9 +633,20 @@ static void
 free_thread_interface (gpointer data)
 {
 	TrackerDBInterface *interface = data;
+	GHashTableIter iter;
+	gpointer value;
 
 	g_static_mutex_lock (&thread_ifaces_mutex);
-	g_hash_table_remove (thread_ifaces, g_thread_self ());
+
+	g_hash_table_iter_init (&iter, thread_ifaces);
+
+	while (g_hash_table_iter_next (&iter, NULL, &value)) {
+		if (value == data) {
+			g_hash_table_iter_remove (&iter);
+			break;
+		}
+	}
+
 	g_static_mutex_unlock (&thread_ifaces_mutex);
 
 	g_object_unref (interface);
diff --git a/src/libtracker-fts/tracker-fts.c b/src/libtracker-fts/tracker-fts.c
index 857b3f8..c2f6f60 100644
--- a/src/libtracker-fts/tracker-fts.c
+++ b/src/libtracker-fts/tracker-fts.c
@@ -2129,6 +2129,7 @@ static int sql_prepare(sqlite3 *db, const char *zDb, const char *zName,
 typedef struct fulltext_vtab fulltext_vtab;
 
 static GStaticPrivate tracker_fts_vtab_key = G_STATIC_PRIVATE_INIT;
+static GQuark quark_fulltext_vtab = 0;
 static TrackerFtsMapFunc map_function = NULL;
 
 /* A single term in a query is represented by an instances of
@@ -3304,14 +3305,19 @@ static int constructVtab(
   sqlite3 *db,		    /* The SQLite database connection */
   const char *zDb,
   const char *zName,
-  char **pzErr              /* Write any error message here */
+  char **pzErr,             /* Write any error message here */
+  GObject *object
 ){
   fulltext_vtab *v = 0;
   TrackerFTSConfig *config;
   TrackerLanguage *language;
   int min_len, max_len;
 
-  v = g_static_private_get (&tracker_fts_vtab_key);
+  if (G_UNLIKELY (quark_fulltext_vtab == 0)) {
+    quark_fulltext_vtab = g_quark_from_static_string ("quark_fulltext_vtab");
+  }
+
+  v = g_object_get_qdata (object, quark_fulltext_vtab);
 
   if(v) {
     return SQLITE_OK;
@@ -3381,7 +3387,9 @@ static int constructVtab(
 
   FTSTRACE(("FTS3 Connect %p\n", v));
 
-  g_static_private_set (&tracker_fts_vtab_key, v, (GDestroyNotify) fulltext_vtab_destroy);
+  g_static_private_set (&tracker_fts_vtab_key, v, NULL);
+  g_object_set_qdata_full (object, quark_fulltext_vtab, v,
+                           (GDestroyNotify) fulltext_vtab_destroy);
 
   return SQLITE_OK;
 }
@@ -7790,14 +7798,14 @@ int sqlite3Fts3InitHashTable(sqlite3 *, fts3Hash *, const char *);
 ** SQLite. If fts3 is built as a dynamically loadable extension, this
 ** function is called by the sqlite3_extension_init() entry point.
 */
-int tracker_fts_init(sqlite3 *db, int create){
+int tracker_fts_init(sqlite3 *db, int create, GObject *object){
   int rc = SQLITE_OK;
 
   if (create){
     createTables (db, "fulltext", "fts");
   }
 
-  constructVtab(db, "fulltext", "fts", NULL);
+  constructVtab(db, "fulltext", "fts", NULL, object);
 
   /* Create the virtual table wrapper around the hash-table and overload
   ** the two scalar functions. If this is successful, register the
@@ -7827,8 +7835,8 @@ int tracker_fts_init(sqlite3 *db, int create){
   return rc;
 }
 
-void tracker_fts_shutdown (void){
-  g_static_private_set (&tracker_fts_vtab_key, NULL, NULL);
+void tracker_fts_shutdown (GObject *object){
+  g_object_set_qdata (object, quark_fulltext_vtab, NULL);
 }
 
 void tracker_fts_shutdown_all (void){
diff --git a/src/libtracker-fts/tracker-fts.h b/src/libtracker-fts/tracker-fts.h
index 2ed6caf..ba6522a 100644
--- a/src/libtracker-fts/tracker-fts.h
+++ b/src/libtracker-fts/tracker-fts.h
@@ -19,13 +19,14 @@
 
 #include <sqlite3.h>
 #include <glib.h>
+#include <glib-object.h>
 
 G_BEGIN_DECLS
 
 typedef const gchar *(*TrackerFtsMapFunc) (gint id);
 
-int tracker_fts_init (sqlite3 *db, int create);
-void tracker_fts_shutdown (void);
+int tracker_fts_init (sqlite3 *db, int create, GObject *object);
+void tracker_fts_shutdown (GObject *object);
 void tracker_fts_shutdown_all (void);
 void tracker_fts_set_map_function (TrackerFtsMapFunc map_func);
 int tracker_fts_update_init (int id);



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