summaryrefslogtreecommitdiff
path: root/src/libtracker-sparql/direct/tracker-direct.c
diff options
context:
space:
mode:
authorCarlos Garnacho <carlosg@gnome.org>2020-08-30 19:33:12 +0200
committerCarlos Garnacho <carlosg@gnome.org>2020-08-30 23:31:52 +0200
commit7683955ebcbb9cb81a0a859fb0737522149bb60e (patch)
tree8281e5bac24ab9494d7053b1c604c6f9760d6707 /src/libtracker-sparql/direct/tracker-direct.c
parenta763f16a94e3c80dda4a5087d92aee28c86b1c9c (diff)
downloadtracker-7683955ebcbb9cb81a0a859fb0737522149bb60e.tar.gz
libtracker-sparql/direct: Set up cleanup timeout
This timeout checks every 30 seconds that the sparql connection has been inactive for some time, and triggers memory to be reclaimed in the update thread.
Diffstat (limited to 'src/libtracker-sparql/direct/tracker-direct.c')
-rw-r--r--src/libtracker-sparql/direct/tracker-direct.c69
1 files changed, 69 insertions, 0 deletions
diff --git a/src/libtracker-sparql/direct/tracker-direct.c b/src/libtracker-sparql/direct/tracker-direct.c
index 07423c47b..3d867283c 100644
--- a/src/libtracker-sparql/direct/tracker-direct.c
+++ b/src/libtracker-sparql/direct/tracker-direct.c
@@ -45,6 +45,11 @@ struct _TrackerDirectConnectionPrivate
GList *notifiers;
+ gint64 timestamp;
+ gint64 cleanup_timestamp;
+
+ guint cleanup_timeout_id;
+
guint initialized : 1;
guint closing : 1;
};
@@ -63,6 +68,7 @@ typedef enum {
TASK_TYPE_QUERY,
TASK_TYPE_UPDATE,
TASK_TYPE_UPDATE_BLANK,
+ TASK_TYPE_RELEASE_MEMORY,
} TaskType;
typedef struct {
@@ -103,6 +109,37 @@ task_data_free (TaskData *task)
g_free (task);
}
+static gboolean
+cleanup_timeout_cb (gpointer user_data)
+{
+ TrackerDirectConnection *conn = user_data;
+ TrackerDirectConnectionPrivate *priv;
+ gint64 timestamp;
+ GTask *task;
+
+ priv = tracker_direct_connection_get_instance_private (conn);
+ timestamp = g_get_monotonic_time ();
+
+ /* If we already cleaned up */
+ if (priv->timestamp < priv->cleanup_timestamp)
+ return G_SOURCE_CONTINUE;
+ /* If the connection was used less than 10s ago */
+ if (timestamp - priv->timestamp < 10 * G_USEC_PER_SEC)
+ return G_SOURCE_CONTINUE;
+
+ priv->cleanup_timestamp = timestamp;
+
+ task = g_task_new (conn, NULL, NULL, NULL);
+ g_task_set_task_data (task,
+ task_data_query_new (TASK_TYPE_RELEASE_MEMORY, NULL),
+ (GDestroyNotify) task_data_free);
+
+ g_thread_pool_push (priv->update_thread, task, NULL);
+
+ return G_SOURCE_CONTINUE;
+}
+
+
static void
update_thread_func (gpointer data,
gpointer user_data)
@@ -115,6 +152,7 @@ update_thread_func (gpointer data,
GError *error = NULL;
gpointer retval = NULL;
GDestroyNotify destroy_notify = NULL;
+ gboolean update_timestamp = TRUE;
conn = user_data;
priv = tracker_direct_connection_get_instance_private (conn);
@@ -133,6 +171,10 @@ update_thread_func (gpointer data,
retval = tracker_data_update_sparql_blank (tracker_data, task_data->query, &error);
destroy_notify = (GDestroyNotify) g_variant_unref;
break;
+ case TASK_TYPE_RELEASE_MEMORY:
+ tracker_data_manager_release_memory (priv->data_manager);
+ update_timestamp = FALSE;
+ break;
}
if (error)
@@ -143,6 +185,10 @@ update_thread_func (gpointer data,
g_task_return_boolean (task, TRUE);
g_object_unref (task);
+
+ if (update_timestamp)
+ tracker_direct_connection_update_timestamp (conn);
+
g_mutex_unlock (&priv->mutex);
}
@@ -284,6 +330,9 @@ tracker_direct_connection_initable_init (GInitable *initable,
g_hash_table_unref (namespaces);
+ priv->cleanup_timeout_id =
+ g_timeout_add_seconds (30, cleanup_timeout_cb, conn);
+
return TRUE;
}
@@ -542,6 +591,9 @@ tracker_direct_connection_finalize (GObject *object)
conn = TRACKER_DIRECT_CONNECTION (object);
priv = tracker_direct_connection_get_instance_private (conn);
+ if (!priv->closing)
+ tracker_sparql_connection_close (TRACKER_SPARQL_CONNECTION (object));
+
g_clear_object (&priv->store);
g_clear_object (&priv->ontology);
g_clear_object (&priv->namespace_manager);
@@ -623,6 +675,7 @@ tracker_direct_connection_query (TrackerSparqlConnection *self,
g_mutex_lock (&priv->mutex);
query = tracker_sparql_new (priv->data_manager, sparql);
cursor = tracker_sparql_execute_cursor (query, NULL, &inner_error);
+ tracker_direct_connection_update_timestamp (conn);
g_object_unref (query);
if (cursor)
@@ -695,6 +748,7 @@ tracker_direct_connection_update (TrackerSparqlConnection *self,
g_mutex_lock (&priv->mutex);
data = tracker_data_manager_get_data (priv->data_manager);
tracker_data_update_sparql (data, sparql, &inner_error);
+ tracker_direct_connection_update_timestamp (conn);
g_mutex_unlock (&priv->mutex);
if (inner_error)
@@ -802,6 +856,7 @@ tracker_direct_connection_update_blank (TrackerSparqlConnection *self,
g_mutex_lock (&priv->mutex);
data = tracker_data_manager_get_data (priv->data_manager);
blank_nodes = tracker_data_update_sparql_blank (data, sparql, &inner_error);
+ tracker_direct_connection_update_timestamp (conn);
g_mutex_unlock (&priv->mutex);
if (inner_error)
@@ -899,6 +954,11 @@ tracker_direct_connection_close (TrackerSparqlConnection *self)
priv = tracker_direct_connection_get_instance_private (conn);
priv->closing = TRUE;
+ if (priv->cleanup_timeout_id) {
+ g_source_remove (priv->cleanup_timeout_id);
+ priv->cleanup_timeout_id = 0;
+ }
+
if (priv->update_thread) {
g_thread_pool_free (priv->update_thread, TRUE, TRUE);
priv->update_thread = NULL;
@@ -1040,3 +1100,12 @@ tracker_direct_connection_get_data_manager (TrackerDirectConnection *conn)
priv = tracker_direct_connection_get_instance_private (conn);
return priv->data_manager;
}
+
+void
+tracker_direct_connection_update_timestamp (TrackerDirectConnection *conn)
+{
+ TrackerDirectConnectionPrivate *priv;
+
+ priv = tracker_direct_connection_get_instance_private (conn);
+ priv->timestamp = g_get_monotonic_time ();
+}