From 053154dc56fcc5c2f46d864de282cb8166cb5b11 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Mon, 27 Aug 2018 21:35:58 +0200 Subject: libtracker-data: Avoid refcount leaks on ontology updates Make sure we add the new triggers after the "rename table, create replacement one, dump data" dance we do on ontology changes. This will avoid leaks as the last step there would increase refcount for all involved resources. There is only one situation where this does not work: Ontology changes that remove properties with rdfs:Resource range will result in those resources being leaked. This breaks differently but in similar ways for single-valued and multivalued properties, in the first we fail to delete elements from the old table, in the second we fail to delete the table altogether. This barely ever happens, so a FIXME has been added, we should cross this bridge before doing any such modification in the ontology. --- src/libtracker-data/tracker-data-manager.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/libtracker-data/tracker-data-manager.c b/src/libtracker-data/tracker-data-manager.c index 6dbe664f4..06012b427 100644 --- a/src/libtracker-data/tracker-data-manager.c +++ b/src/libtracker-data/tracker-data-manager.c @@ -3373,10 +3373,6 @@ create_decomposed_metadata_tables (TrackerDataManager *manager, g_debug ("Creating: '%s'", create_sql->str); tracker_db_interface_execute_query (iface, &internal_error, "%s", create_sql->str); - - if (!internal_error) - create_table_triggers (manager, iface, service, &internal_error); - if (internal_error) { g_propagate_error (error, internal_error); goto error_out; @@ -3488,6 +3484,19 @@ create_decomposed_metadata_tables (TrackerDataManager *manager, } } + if (!in_update || in_change || tracker_class_get_is_new (service)) { + /* FIXME: We are trusting object refcount will stay intact across + * ontology changes. One situation where this is not true are + * removal or properties with rdfs:Resource range. + */ + create_table_triggers (manager, iface, service, &internal_error); + + if (internal_error) { + g_propagate_error (error, internal_error); + goto error_out; + } + } + if (copy_schedule) { guint i; for (i = 0; i < copy_schedule->len; i++) { -- cgit v1.2.1