[tracker/wip/carlosg/timeouts-and-stuff: 2/2] libtracker-data: Protect tracker_sparql_execute_cursor() with a mutex
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tracker/wip/carlosg/timeouts-and-stuff: 2/2] libtracker-data: Protect tracker_sparql_execute_cursor() with a mutex
- Date: Fri, 3 Jul 2020 10:10:51 +0000 (UTC)
commit 7eb1ca0858841ddbf0680f95e542c5d29e869ab9
Author: Carlos Garnacho <carlosg gnome org>
Date: Fri Jul 3 12:01:37 2020 +0200
libtracker-data: Protect tracker_sparql_execute_cursor() with a mutex
This function used to operate 100% on readonly data, so could be safely
used from multiple threads. This is however no longer true since commit
af97cede7ced, which might result in TrackerSparql churning again to
re-parse the SPARQL into SQL.
Moreover, as this was not an atomic operation (far from it), the same
TrackerSparql could trigger independently this re-parsing, or surprise
older users with data going down their feet. This could produce anything
from wrong results, to invalid reads/writes, to crashes.
Protect the whole thing with a mutex, so it is ensured it's only rebuilt
in one thread, and other users don't get surprised by it.
src/libtracker-data/tracker-sparql.c | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
---
diff --git a/src/libtracker-data/tracker-sparql.c b/src/libtracker-data/tracker-sparql.c
index 937b475cb..8e87d9fb5 100644
--- a/src/libtracker-data/tracker-sparql.c
+++ b/src/libtracker-data/tracker-sparql.c
@@ -137,6 +137,8 @@ struct _TrackerSparql
GPtrArray *named_graphs;
gchar *base;
+ GMutex mutex;
+
struct {
TrackerContext *context;
TrackerContext *select_context;
@@ -8795,6 +8797,7 @@ tracker_sparql_init (TrackerSparql *sparql)
sparql->anon_graphs = g_ptr_array_new_with_free_func (g_free);
sparql->named_graphs = g_ptr_array_new_with_free_func (g_free);
sparql->cacheable = TRUE;
+ g_mutex_init (&sparql->mutex);
}
static gboolean
@@ -8967,11 +8970,13 @@ tracker_sparql_execute_cursor (TrackerSparql *sparql,
{
TrackerDBStatement *stmt;
TrackerDBInterface *iface;
- TrackerDBCursor *cursor;
+ TrackerDBCursor *cursor = NULL;
TrackerPropertyType *types;
const gchar * const *names;
guint n_types, n_names;
+ g_mutex_lock (&sparql->mutex);
+
#ifdef G_ENABLE_DEBUG
if (TRACKER_DEBUG_CHECK (SPARQL)) {
gchar *query_to_print;
@@ -8985,14 +8990,14 @@ tracker_sparql_execute_cursor (TrackerSparql *sparql,
if (sparql->parser_error) {
g_propagate_error (error, sparql->parser_error);
- return NULL;
+ goto error;
}
if (tracker_sparql_needs_update (sparql)) {
tracker_sparql_reset_state (sparql);
if (!_call_rule_func (sparql, NAMED_RULE_Query, error))
- return NULL;
+ goto error;
}
iface = tracker_data_manager_get_db_interface (sparql->data_manager);
@@ -9002,7 +9007,7 @@ tracker_sparql_execute_cursor (TrackerSparql *sparql,
sparql->cacheable,
error);
if (!stmt)
- return NULL;
+ goto error;
types = (TrackerPropertyType *) sparql->var_types->data;
n_types = sparql->var_types->len;
@@ -9015,7 +9020,11 @@ tracker_sparql_execute_cursor (TrackerSparql *sparql,
error);
g_object_unref (stmt);
+error:
+ g_mutex_unlock (&sparql->mutex);
+
return TRACKER_SPARQL_CURSOR (cursor);
+
}
TrackerSparql *
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]