[tracker/sql-error-checks-for-master: 4/7] libtracker-db: Fixed a race condition in interrupt handling



commit 135eeb8a11a63a3a88423a6e8d03ca9e9d3f396d
Author: Philip Van Hoof <philip codeminded be>
Date:   Tue May 25 17:15:19 2010 +0200

    libtracker-db: Fixed a race condition in interrupt handling

 src/libtracker-data/tracker-data-manager.c      |    8 ++-
 src/libtracker-data/tracker-data-manager.h      |   71 ++++++++++++-----------
 src/libtracker-db/tracker-db-interface-sqlite.c |   11 +++-
 src/libtracker-db/tracker-db-interface.c        |   15 +++++
 src/libtracker-db/tracker-db-interface.h        |    2 +
 src/libtracker-db/tracker-db-manager.c          |   70 +++++++++++++++-------
 src/libtracker-db/tracker-db-manager.h          |   33 ++++++-----
 src/tracker-store/tracker-store.c               |    4 +-
 8 files changed, 137 insertions(+), 77 deletions(-)
---
diff --git a/src/libtracker-data/tracker-data-manager.c b/src/libtracker-data/tracker-data-manager.c
index ccbecf9..f2e8d6e 100644
--- a/src/libtracker-data/tracker-data-manager.c
+++ b/src/libtracker-data/tracker-data-manager.c
@@ -2626,7 +2626,7 @@ tracker_data_manager_get_db_option_int64 (const gchar *option)
 	if (error) {
 		g_warning ("%s", error->message);
 		g_error_free (error);
-		return;
+		return -1;
 	}
 
 	return value;
@@ -2670,3 +2670,9 @@ tracker_data_manager_interrupt_thread (GThread *thread)
 {
 	return tracker_db_manager_interrupt_thread (thread);
 }
+
+void
+tracker_data_manager_interrupt_thread_reset (GThread *thread)
+{
+	tracker_db_manager_interrupt_thread_reset (thread);
+}
diff --git a/src/libtracker-data/tracker-data-manager.h b/src/libtracker-data/tracker-data-manager.h
index e83d6c7..56a6535 100644
--- a/src/libtracker-data/tracker-data-manager.h
+++ b/src/libtracker-data/tracker-data-manager.h
@@ -39,42 +39,43 @@ G_BEGIN_DECLS
 #error "only <libtracker-data/tracker-data.h> must be included directly."
 #endif
 
-gboolean tracker_data_manager_init                (TrackerDBManagerFlags  flags,
-                                                   const gchar          **test_schema,
-                                                   gboolean              *first_time,
-                                                   gboolean               journal_check,
-                                                   TrackerBusyCallback    busy_callback,
-                                                   gpointer               busy_user_data,
-                                                   const gchar           *busy_status);
-void     tracker_data_manager_shutdown            (void);
-gboolean tracker_data_manager_interrupt_thread    (GThread               *thread);
+gboolean tracker_data_manager_init                   (TrackerDBManagerFlags  flags,
+                                                      const gchar          **test_schema,
+                                                      gboolean              *first_time,
+                                                      gboolean               journal_check,
+                                                      TrackerBusyCallback    busy_callback,
+                                                      gpointer               busy_user_data,
+                                                      const gchar           *busy_status);
+void     tracker_data_manager_shutdown               (void);
+gboolean tracker_data_manager_interrupt_thread       (GThread               *thread);
+void     tracker_data_manager_interrupt_thread_reset (GThread               *thread);
 
-gint64   tracker_data_manager_get_db_option_int64 (const gchar           *option);
-void     tracker_data_manager_set_db_option_int64 (const gchar           *option,
-                                                   gint64                 value);
-void     tracker_data_ontology_load_statement     (const gchar           *ontology_file,
-                                                   gint                   subject_id,
-                                                   const gchar           *subject,
-                                                   const gchar           *predicate,
-                                                   const gchar           *object,
-                                                   gint                  *max_id,
-                                                   gboolean               in_update,
-                                                   GHashTable            *classes,
-                                                   GHashTable            *properties,
-                                                   GPtrArray             *seen_classes,
-                                                   GPtrArray             *seen_properties);
-void     tracker_data_ontology_import_into_db     (gboolean               is_new);
-void     tracker_data_ontology_process_statement  (const gchar           *graph,
-                                                   const gchar           *subject,
-                                                   const gchar           *predicate,
-                                                   const gchar           *object,
-                                                   gboolean               is_uri,
-                                                   gboolean               in_update,
-                                                   gboolean               ignore_nao_last_modified);
-void    tracker_data_ontology_import_finished     (void);
-void    tracker_data_ontology_process_changes     (GPtrArray             *seen_classes,
-                                                   GPtrArray             *seen_properties);
-void    tracker_data_ontology_free_seen           (GPtrArray             *seen);
+gint64   tracker_data_manager_get_db_option_int64    (const gchar           *option);
+void     tracker_data_manager_set_db_option_int64    (const gchar           *option,
+                                                      gint64                 value);
+void     tracker_data_ontology_load_statement        (const gchar           *ontology_file,
+                                                      gint                   subject_id,
+                                                      const gchar           *subject,
+                                                      const gchar           *predicate,
+                                                      const gchar           *object,
+                                                      gint                  *max_id,
+                                                      gboolean               in_update,
+                                                      GHashTable            *classes,
+                                                      GHashTable            *properties,
+                                                      GPtrArray             *seen_classes,
+                                                      GPtrArray             *seen_properties);
+void     tracker_data_ontology_import_into_db        (gboolean               is_new);
+void     tracker_data_ontology_process_statement     (const gchar           *graph,
+                                                      const gchar           *subject,
+                                                      const gchar           *predicate,
+                                                      const gchar           *object,
+                                                      gboolean               is_uri,
+                                                      gboolean               in_update,
+                                                      gboolean               ignore_nao_last_modified);
+void    tracker_data_ontology_import_finished        (void);
+void    tracker_data_ontology_process_changes        (GPtrArray             *seen_classes,
+                                                      GPtrArray             *seen_properties);
+void    tracker_data_ontology_free_seen              (GPtrArray             *seen);
 
 G_END_DECLS
 
diff --git a/src/libtracker-db/tracker-db-interface-sqlite.c b/src/libtracker-db/tracker-db-interface-sqlite.c
index 583429b..2eb1140 100644
--- a/src/libtracker-db/tracker-db-interface-sqlite.c
+++ b/src/libtracker-db/tracker-db-interface-sqlite.c
@@ -91,7 +91,7 @@ struct TrackerDBInterfaceSqlitePrivate {
 	guint in_transaction : 1;
 	guint ro : 1;
 	guint fts_initialized : 1;
-	gint interrupt;
+	volatile gint interrupt;
 };
 
 struct TrackerDBStatementSqlitePrivate {
@@ -953,11 +953,20 @@ tracker_db_interface_sqlite_interrupt (TrackerDBInterface *iface)
 }
 
 static void
+tracker_db_interface_sqlite_reset_interrupt (TrackerDBInterface *iface)
+{
+	TrackerDBInterfaceSqlitePrivate *priv;
+	priv = TRACKER_DB_INTERFACE_SQLITE_GET_PRIVATE (iface);
+	priv->interrupt = 0;
+}
+
+static void
 tracker_db_interface_sqlite_iface_init (TrackerDBInterfaceIface *iface)
 {
 	iface->create_statement = tracker_db_interface_sqlite_create_statement;
 	iface->execute_query = tracker_db_interface_sqlite_execute_query;
 	iface->interrupt = tracker_db_interface_sqlite_interrupt;
+	iface->reset_interrupt = tracker_db_interface_sqlite_reset_interrupt;
 }
 
 TrackerDBInterface *
diff --git a/src/libtracker-db/tracker-db-interface.c b/src/libtracker-db/tracker-db-interface.c
index 98bc6c2..379a3d4 100644
--- a/src/libtracker-db/tracker-db-interface.c
+++ b/src/libtracker-db/tracker-db-interface.c
@@ -326,6 +326,21 @@ tracker_db_interface_interrupt (TrackerDBInterface *interface)
 	return TRACKER_DB_INTERFACE_GET_IFACE (interface)->interrupt (interface);
 }
 
+void
+tracker_db_interface_reset_interrupt (TrackerDBInterface *interface)
+{
+	g_return_if_fail (TRACKER_IS_DB_INTERFACE (interface));
+
+	if (!TRACKER_DB_INTERFACE_GET_IFACE (interface)->reset_interrupt) {
+		g_critical ("Database abstraction %s doesn't implement "
+		            "the method reset_interrupt()",
+		            G_OBJECT_TYPE_NAME (interface));
+		return;
+	}
+
+	TRACKER_DB_INTERFACE_GET_IFACE (interface)->reset_interrupt (interface);
+}
+
 gboolean
 tracker_db_interface_start_transaction (TrackerDBInterface *interface)
 {
diff --git a/src/libtracker-db/tracker-db-interface.h b/src/libtracker-db/tracker-db-interface.h
index 585130a..459dde4 100644
--- a/src/libtracker-db/tracker-db-interface.h
+++ b/src/libtracker-db/tracker-db-interface.h
@@ -78,6 +78,7 @@ struct TrackerDBInterfaceIface {
 	                                           GError             **error,
 	                                           const gchar         *query);
 	gboolean             (* interrupt)        (TrackerDBInterface  *interface);
+	void                 (* reset_interrupt)  (TrackerDBInterface  *interface);
 };
 
 struct TrackerDBStatementIface {
@@ -153,6 +154,7 @@ TrackerDBResultSet *tracker_db_interface_execute_query     (TrackerDBInterface
                                                             ...) G_GNUC_PRINTF (3, 4);
 
 gboolean            tracker_db_interface_interrupt         (TrackerDBInterface  *interface);
+void                tracker_db_interface_reset_interrupt   (TrackerDBInterface  *interface);
 gboolean            tracker_db_interface_start_transaction (TrackerDBInterface  *interface);
 gboolean            tracker_db_interface_end_db_transaction(TrackerDBInterface  *interface);
 void                tracker_db_statement_bind_double       (TrackerDBStatement  *stmt,
diff --git a/src/libtracker-db/tracker-db-manager.c b/src/libtracker-db/tracker-db-manager.c
index e2aaf27..6fa92f8 100644
--- a/src/libtracker-db/tracker-db-manager.c
+++ b/src/libtracker-db/tracker-db-manager.c
@@ -1288,29 +1288,6 @@ tracker_db_manager_has_enough_space  (void)
 	return tracker_file_system_has_enough_space (data_dir, TRACKER_DB_MIN_REQUIRED_SPACE, FALSE);
 }
 
-/**
- * tracker_db_manager_interrupt_thread:
- * @thread: a #GThread to be interrupted
- *
- * Interrupts any ongoing DB operation going on on @thread.
- *
- * Returns: %TRUE if DB operations were interrupted, %FALSE otherwise.
- **/
-gboolean
-tracker_db_manager_interrupt_thread (GThread *thread)
-{
-	TrackerDBInterface *interface;
-
-	g_static_mutex_lock (&thread_ifaces_mutex);
-	interface = g_hash_table_lookup (thread_ifaces, thread);
-	g_static_mutex_unlock (&thread_ifaces_mutex);
-
-	if (!interface) {
-		return FALSE;
-	}
-
-	return tracker_db_interface_interrupt (interface);
-}
 
 static gchar *
 get_first_index_stamp_path (void)
@@ -1387,3 +1364,50 @@ tracker_db_manager_set_first_index_done (gboolean done)
 
 	g_free (stamp);
 }
+
+/**
+ * tracker_db_manager_interrupt_thread:
+ * @thread: a #GThread to be interrupted
+ *
+ * Interrupts any ongoing DB operation going on on @thread.
+ *
+ * Returns: %TRUE if DB operations were interrupted, %FALSE otherwise.
+ **/
+gboolean
+tracker_db_manager_interrupt_thread (GThread *thread)
+{
+	TrackerDBInterface *interface;
+
+	g_static_mutex_lock (&thread_ifaces_mutex);
+	interface = g_hash_table_lookup (thread_ifaces, thread);
+	g_static_mutex_unlock (&thread_ifaces_mutex);
+
+	if (!interface) {
+		return FALSE;
+	}
+
+	return tracker_db_interface_interrupt (interface);
+}
+
+/**
+ * tracker_db_manager_interrupt_thread_reset:
+ * @thread: a #GThread to be reset
+ *
+ * Reset @thread's interrupt state
+ *
+ **/
+void
+tracker_db_manager_interrupt_thread_reset (GThread *thread)
+{
+	TrackerDBInterface *interface;
+
+	g_static_mutex_lock (&thread_ifaces_mutex);
+	interface = g_hash_table_lookup (thread_ifaces, thread);
+	g_static_mutex_unlock (&thread_ifaces_mutex);
+
+	if (!interface) {
+		return FALSE;
+	}
+
+	tracker_db_interface_reset_interrupt (interface);
+}
diff --git a/src/libtracker-db/tracker-db-manager.h b/src/libtracker-db/tracker-db-manager.h
index 6111306..2859f4b 100644
--- a/src/libtracker-db/tracker-db-manager.h
+++ b/src/libtracker-db/tracker-db-manager.h
@@ -47,25 +47,26 @@ typedef enum {
 	TRACKER_DB_MANAGER_READONLY         = 1 << 5
 } TrackerDBManagerFlags;
 
-GType               tracker_db_get_type                  (void) G_GNUC_CONST;
-gboolean            tracker_db_manager_init              (TrackerDBManagerFlags  flags,
-                                                          gboolean              *first_time,
-                                                          gboolean               shared_cache);
-void                tracker_db_manager_shutdown          (void);
-void                tracker_db_manager_remove_all        (gboolean               rm_journal);
-void                tracker_db_manager_optimize          (void);
-const gchar *       tracker_db_manager_get_file          (TrackerDB              db);
-TrackerDBInterface *tracker_db_manager_get_db_interface  (void);
-void                tracker_db_manager_remove_temp       (void);
-void                tracker_db_manager_move_to_temp      (void);
-void                tracker_db_manager_restore_from_temp (void);
-void                tracker_db_manager_init_locations    (void);
-gboolean            tracker_db_manager_has_enough_space  (void);
+GType               tracker_db_get_type                       (void) G_GNUC_CONST;
+gboolean            tracker_db_manager_init                   (TrackerDBManagerFlags  flags,
+                                                               gboolean              *first_time,
+                                                               gboolean               shared_cache);
+void                tracker_db_manager_shutdown               (void);
+void                tracker_db_manager_remove_all             (gboolean               rm_journal);
+void                tracker_db_manager_optimize               (void);
+const gchar *       tracker_db_manager_get_file               (TrackerDB              db);
+TrackerDBInterface *tracker_db_manager_get_db_interface       (void);
+void                tracker_db_manager_remove_temp            (void);
+void                tracker_db_manager_move_to_temp           (void);
+void                tracker_db_manager_restore_from_temp      (void);
+void                tracker_db_manager_init_locations         (void);
+gboolean            tracker_db_manager_has_enough_space       (void);
 
 TrackerDBManagerFlags
-                    tracker_db_manager_get_flags         (void);
+                    tracker_db_manager_get_flags              (void);
 
-gboolean            tracker_db_manager_interrupt_thread  (GThread *thread);
+gboolean            tracker_db_manager_interrupt_thread       (GThread *thread);
+void                tracker_db_manager_interrupt_thread_reset (GThread *thread);
 
 gboolean            tracker_db_manager_get_first_index_done (void);
 void                tracker_db_manager_set_first_index_done (gboolean done);
diff --git a/src/tracker-store/tracker-store.c b/src/tracker-store/tracker-store.c
index 513a8d5..495e874 100644
--- a/src/tracker-store/tracker-store.c
+++ b/src/tracker-store/tracker-store.c
@@ -446,8 +446,10 @@ pool_dispatch_cb (gpointer data,
 
 	if (task->type == TRACKER_STORE_TASK_TYPE_QUERY) {
 		TrackerDBCursor *cursor;
+		GThread *running_thread = g_thread_self ();
 
-		task->data.query.running_thread = g_thread_self ();
+		tracker_data_manager_interrupt_thread_reset (running_thread);
+		task->data.query.running_thread = running_thread;
 		cursor = tracker_data_query_sparql_cursor (task->data.query.query, &task->error);
 
 		task->data.query.thread_data = task->callback.query.in_thread (cursor, task->error, task->user_data);



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