Blame SOURCES/0001-fts-Strengthen-against-sqlite-failures-in-FTS-functi.patch

43271f
From 00b71d0f9ae3f4d2b7bc8fa2afe08cd89c5c9c35 Mon Sep 17 00:00:00 2001
43271f
From: Carlos Garnacho <carlosg@gnome.org>
43271f
Date: Tue, 3 Dec 2013 16:17:54 +0100
43271f
Subject: [PATCH] fts: Strengthen against sqlite failures in FTS functions
43271f
43271f
function_weights() and function_property_names() (used respectively by
43271f
SPARQL fts:rank and fts:offsets functions), initialize all data at first
43271f
from the database, so it's available in memory for posterior runs,
43271f
although currently those are being quite optimistic about the database
43271f
return values in several ways, so:
43271f
43271f
- Ensure no infinite loops happen on sqlite3_step() if the stmt trips
43271f
  into some unexpected state. SQLITE_BUSY still does keep looping though.
43271f
43271f
- As initialization here is a failable task, stop using g_once_init_*
43271f
  and use an static GMutex so initialization can be tried later again
43271f
  if it failed previously.
43271f
43271f
- For the cases where initialization failed, propagate the error code
43271f
  on the sqlite3_context.
43271f
43271f
Based on work by Tim Waugh and Michael Catanzaro.
43271f
https://bugzilla.redhat.com/show_bug.cgi?id=1026283
43271f
---
43271f
 src/libtracker-fts/tracker-fts.c | 52 +++++++++++++++++++++++++++-------------
43271f
 1 file changed, 36 insertions(+), 16 deletions(-)
43271f
43271f
diff --git a/src/libtracker-fts/tracker-fts.c b/src/libtracker-fts/tracker-fts.c
43271f
index 530d831..446a4a6 100644
43271f
--- a/src/libtracker-fts/tracker-fts.c
43271f
+++ b/src/libtracker-fts/tracker-fts.c
43271f
@@ -127,13 +127,15 @@ function_weights (sqlite3_context *context,
43271f
                   sqlite3_value   *argv[])
43271f
 {
43271f
 	static guint *weights = NULL;
43271f
-	static gsize weights_initialized = 0;
43271f
+	static GMutex mutex;
43271f
+	int rc = SQLITE_DONE;
43271f
 
43271f
-	if (g_once_init_enter (&weights_initialized)) {
43271f
+	g_mutex_lock (&mutex);
43271f
+
43271f
+	if (G_UNLIKELY (weights == NULL)) {
43271f
 		GArray *weight_array;
43271f
 		sqlite3_stmt *stmt;
43271f
 		sqlite3 *db;
43271f
-		int rc;
43271f
 
43271f
 		weight_array = g_array_new (FALSE, FALSE, sizeof (guint));
43271f
 		db = sqlite3_context_db_handle (context);
43271f
@@ -149,18 +151,26 @@ function_weights (sqlite3_context *context,
43271f
 				guint weight;
43271f
 				weight = sqlite3_column_int (stmt, 0);
43271f
 				g_array_append_val (weight_array, weight);
43271f
+			} else if (rc != SQLITE_BUSY) {
43271f
+				break;
43271f
 			}
43271f
 		}
43271f
 
43271f
+		sqlite3_finalize (stmt);
43271f
+
43271f
 		if (rc == SQLITE_DONE) {
43271f
-			rc = sqlite3_finalize (stmt);
43271f
+			weights = (guint *) g_array_free (weight_array, FALSE);
43271f
+		} else {
43271f
+			g_array_free (weight_array, TRUE);
43271f
 		}
43271f
-
43271f
-		weights = (guint *) g_array_free (weight_array, FALSE);
43271f
-		g_once_init_leave (&weights_initialized, (rc == SQLITE_OK));
43271f
 	}
43271f
 
43271f
-	sqlite3_result_blob (context, weights, sizeof (weights), NULL);
43271f
+	g_mutex_unlock (&mutex);
43271f
+
43271f
+	if (rc == SQLITE_DONE)
43271f
+		sqlite3_result_blob (context, weights, sizeof (weights), NULL);
43271f
+	else
43271f
+		sqlite3_result_error_code (context, rc);
43271f
 }
43271f
 
43271f
 static void
43271f
@@ -169,13 +179,15 @@ function_property_names (sqlite3_context *context,
43271f
                          sqlite3_value   *argv[])
43271f
 {
43271f
 	static gchar **names = NULL;
43271f
-	static gsize names_initialized = 0;
43271f
+	static GMutex mutex;
43271f
+	int rc = SQLITE_DONE;
43271f
 
43271f
-	if (g_once_init_enter (&names_initialized)) {
43271f
+	g_mutex_lock (&mutex);
43271f
+
43271f
+	if (G_UNLIKELY (names == NULL)) {
43271f
 		GPtrArray *names_array;
43271f
 		sqlite3_stmt *stmt;
43271f
 		sqlite3 *db;
43271f
-		int rc;
43271f
 
43271f
 		names_array = g_ptr_array_new ();
43271f
 		db = sqlite3_context_db_handle (context);
43271f
@@ -194,18 +206,26 @@ function_property_names (sqlite3_context *context,
43271f
 
43271f
 				name = sqlite3_column_text (stmt, 0);
43271f
 				g_ptr_array_add (names_array, g_strdup (name));
43271f
+			} else if (rc != SQLITE_BUSY) {
43271f
+				break;
43271f
 			}
43271f
 		}
43271f
 
43271f
+		sqlite3_finalize (stmt);
43271f
+
43271f
 		if (rc == SQLITE_DONE) {
43271f
-			rc = sqlite3_finalize (stmt);
43271f
+			names = (gchar **) g_ptr_array_free (names_array, FALSE);
43271f
+		} else {
43271f
+			g_ptr_array_free (names_array, TRUE);
43271f
 		}
43271f
-
43271f
-		names = (gchar **) g_ptr_array_free (names_array, FALSE);
43271f
-		g_once_init_leave (&names_initialized, (rc == SQLITE_OK));
43271f
 	}
43271f
 
43271f
-	sqlite3_result_blob (context, names, sizeof (names), NULL);
43271f
+	g_mutex_unlock (&mutex);
43271f
+
43271f
+	if (rc == SQLITE_DONE)
43271f
+		sqlite3_result_blob (context, names, sizeof (names), NULL);
43271f
+	else
43271f
+		sqlite3_result_error_code (context, rc);
43271f
 }
43271f
 
43271f
 static void
43271f
-- 
43271f
1.8.4.2
43271f