[tracker/wip/carlosg/hashtable-ownership: 2/3] libtracker-data: Initialize graphs hashtable early with data manager
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tracker/wip/carlosg/hashtable-ownership: 2/3] libtracker-data: Initialize graphs hashtable early with data manager
- Date: Sun, 5 Dec 2021 22:53:07 +0000 (UTC)
commit 7f22a16921163e8bc6f1a8032165729949b8569f
Author: Carlos Garnacho <carlosg gnome org>
Date: Sun Dec 5 23:20:09 2021 +0100
libtracker-data: Initialize graphs hashtable early with data manager
We are lazily creating this hashtable, however this looks like a bad idea
since this API may be accessed from multiple threads. Ensure it's first
initialized during TrackerDataManager initialization, and ensure to return
a reference to the hashtable so the caller can operate on it without fear
of it being freed underneath.
Hopefully, this fixes some strange crashes spotted in Fedora Retrace
service, since the hashtable might be changed from other threads while
another one is iterating across it. E.g.:
https://retrace.fedoraproject.org/faf/problems/bthash/?bth=f695d55500ad18a095fbd42dbb92bace62f684fa
src/libtracker-data/tracker-data-manager.c | 87 +++++++++++++++---------------
src/libtracker-data/tracker-sparql.c | 4 +-
2 files changed, 48 insertions(+), 43 deletions(-)
---
diff --git a/src/libtracker-data/tracker-data-manager.c b/src/libtracker-data/tracker-data-manager.c
index 0a0c44f63..a78996fd0 100644
--- a/src/libtracker-data/tracker-data-manager.c
+++ b/src/libtracker-data/tracker-data-manager.c
@@ -158,18 +158,15 @@ tracker_data_ontology_error_quark (void)
return g_quark_from_static_string ("tracker-data-ontology-error-quark");
}
-static GHashTable *
-tracker_data_manager_ensure_graphs (TrackerDataManager *manager,
- TrackerDBInterface *iface,
- GError **error)
+static gboolean
+tracker_data_manager_initialize_graphs (TrackerDataManager *manager,
+ TrackerDBInterface *iface,
+ GError **error)
{
TrackerDBCursor *cursor = NULL;
TrackerDBStatement *stmt;
GHashTable *graphs;
- if (manager->graphs)
- return manager->graphs;
-
graphs = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
@@ -179,7 +176,7 @@ tracker_data_manager_ensure_graphs (TrackerDataManager *manager,
"SELECT ID, Uri FROM Resource WHERE ID IN (SELECT ID
FROM Graph)");
if (!stmt) {
g_hash_table_unref (graphs);
- return NULL;
+ return FALSE;
}
cursor = tracker_db_statement_start_cursor (stmt, error);
@@ -187,7 +184,7 @@ tracker_data_manager_ensure_graphs (TrackerDataManager *manager,
if (!cursor) {
g_hash_table_unref (graphs);
- return NULL;
+ return FALSE;
}
while (tracker_db_cursor_iter_next (cursor, NULL, NULL)) {
@@ -203,17 +200,21 @@ tracker_data_manager_ensure_graphs (TrackerDataManager *manager,
g_object_unref (cursor);
manager->graphs = graphs;
- return graphs;
+ return TRUE;
}
GHashTable *
tracker_data_manager_get_graphs (TrackerDataManager *manager,
gboolean in_transaction)
{
+ GHashTable *ht;
+
if (manager->transaction_graphs && in_transaction)
- return manager->transaction_graphs;
+ ht = g_hash_table_ref (manager->transaction_graphs);
+ else
+ ht = g_hash_table_ref (manager->graphs);
- return manager->graphs;
+ return ht;
}
static void
@@ -773,19 +774,12 @@ fix_indexed (TrackerDataManager *manager,
TrackerProperty *property,
GError **error)
{
- TrackerDBInterface *iface;
GHashTable *graphs;
GHashTableIter iter;
GError *internal_error = NULL;
gpointer value;
- iface = tracker_data_manager_get_writable_db_interface (manager);
- graphs = tracker_data_manager_ensure_graphs (manager, iface, &internal_error);
- if (internal_error) {
- g_propagate_error (error, internal_error);
- return;
- }
-
+ graphs = tracker_data_manager_get_graphs (manager, FALSE);
g_hash_table_iter_init (&iter, graphs);
while (g_hash_table_iter_next (&iter, &value, NULL)) {
@@ -795,6 +789,8 @@ fix_indexed (TrackerDataManager *manager,
break;
}
}
+
+ g_hash_table_unref (graphs);
}
static void
@@ -3870,7 +3866,7 @@ tracker_data_manager_initialize_iface (TrackerDataManager *data_manager,
{
GHashTable *graphs;
- graphs = tracker_data_manager_ensure_graphs (data_manager, iface, NULL);
+ graphs = tracker_data_manager_get_graphs (data_manager, FALSE);
if (graphs) {
GHashTableIter iter;
@@ -3881,20 +3877,24 @@ tracker_data_manager_initialize_iface (TrackerDataManager *data_manager,
while (g_hash_table_iter_next (&iter, &value, NULL)) {
if (!tracker_db_manager_attach_database (data_manager->db_manager,
iface, value, FALSE,
- error)) {
- return FALSE;
- }
+ error))
+ goto error;
if (!tracker_data_manager_init_fts (data_manager, iface,
value, FALSE, error))
- return FALSE;
+ goto error;
}
+
+ g_hash_table_unref (graphs);
}
if (!tracker_data_manager_init_fts (data_manager, iface, "main", FALSE, error))
return FALSE;
return TRUE;
+ error:
+ g_clear_pointer (&graphs, g_hash_table_unref);
+ return FALSE;
}
static void
@@ -4174,6 +4174,11 @@ tracker_data_manager_initable_init (GInitable *initable,
goto rollback_newly_created_db;
}
+ if (!tracker_data_manager_initialize_graphs (manager, iface, &internal_error)) {
+ g_propagate_error (error, internal_error);
+ goto rollback_newly_created_db;
+ }
+
tracker_data_manager_initialize_iface (manager, iface, &internal_error);
if (internal_error) {
g_propagate_error (error, internal_error);
@@ -4251,6 +4256,11 @@ tracker_data_manager_initable_init (GInitable *initable,
}
}
+ if (!tracker_data_manager_initialize_graphs (manager, iface, &internal_error)) {
+ g_propagate_error (error, internal_error);
+ return FALSE;
+ }
+
tracker_data_manager_initialize_iface (manager, iface, &internal_error);
if (internal_error) {
g_propagate_error (error, internal_error);
@@ -4515,7 +4525,7 @@ tracker_data_manager_initable_init (GInitable *initable,
tracker_data_ontology_setup_db (manager, iface, "main", TRUE,
&ontology_error);
if (!ontology_error)
- graphs = tracker_data_manager_ensure_graphs (manager, iface,
&ontology_error);
+ graphs = tracker_data_manager_get_graphs (manager, FALSE);
if (graphs) {
GHashTableIter iter;
@@ -4544,6 +4554,8 @@ tracker_data_manager_initable_init (GInitable *initable,
if (ontology_error)
break;
}
+
+ g_hash_table_unref (graphs);
}
if (!ontology_error) {
@@ -4681,9 +4693,7 @@ data_manager_perform_cleanup (TrackerDataManager *manager,
const gchar *graph;
GString *str;
- graphs = tracker_data_manager_ensure_graphs (manager, iface, &internal_error);
- if (!graphs)
- goto fail;
+ graphs = tracker_data_manager_get_graphs (manager, FALSE);
str = g_string_new ("WITH referencedElements(ID) AS ("
"SELECT ID FROM \"main\".Refcount ");
@@ -4701,6 +4711,7 @@ data_manager_perform_cleanup (TrackerDataManager *manager,
"DELETE FROM Resource "
"WHERE Resource.ID NOT IN (SELECT ID FROM referencedElements) "
"AND Resource.ID NOT IN (SELECT ID FROM Graph)");
+ g_hash_table_unref (graphs);
stmt = tracker_db_interface_create_statement (iface,
TRACKER_DB_STATEMENT_CACHE_TYPE_UPDATE,
@@ -4971,22 +4982,14 @@ tracker_data_manager_find_graph (TrackerDataManager *manager,
const gchar *name,
gboolean in_transaction)
{
- TrackerDBInterface *iface;
GHashTable *graphs;
+ gint graph_id;
- iface = tracker_db_manager_get_writable_db_interface (manager->db_manager);
-
- if (in_transaction && manager->transaction_graphs) {
- return GPOINTER_TO_INT (g_hash_table_lookup (manager->transaction_graphs,
- name));
- }
-
- graphs = tracker_data_manager_ensure_graphs (manager, iface, NULL);
-
- if (!graphs)
- return 0;
+ graphs = tracker_data_manager_get_graphs (manager, in_transaction);
+ graph_id = GPOINTER_TO_UINT (g_hash_table_lookup (graphs, name));
+ g_hash_table_unref (graphs);
- return GPOINTER_TO_UINT (g_hash_table_lookup (graphs, name));
+ return graph_id;
}
gboolean
diff --git a/src/libtracker-data/tracker-sparql.c b/src/libtracker-data/tracker-sparql.c
index 1e238c71a..222a3c0bc 100644
--- a/src/libtracker-data/tracker-sparql.c
+++ b/src/libtracker-data/tracker-sparql.c
@@ -711,9 +711,11 @@ tracker_sparql_get_effective_graphs (TrackerSparql *sparql)
}
}
+ g_hash_table_unref (graphs);
+
return g_hash_table_ref (sparql->policy.filtered_graphs);
} else {
- return g_hash_table_ref (graphs);
+ return graphs;
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]