[tracker/sql-error-checks-for-master: 4/7] libtracker-db: Fixed a race condition in interrupt handling
- From: Philip Van Hoof <pvanhoof src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tracker/sql-error-checks-for-master: 4/7] libtracker-db: Fixed a race condition in interrupt handling
- Date: Wed, 26 May 2010 11:22:16 +0000 (UTC)
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]