Skip to content

Commit

Permalink
daemon: Exit on idle after txn
Browse files Browse the repository at this point in the history
So...we have some bad memory leaks somewhere. We go from 14MB RSS after being
activated from `atomic host status` to 54MB after a dummy `rpm-ostree install
foo`, 80MB for a successful install, and I've seen it as high as 140MB.

Exiting on idle is what PackageKit has done forever. One problem particularly
for both of us is that libdnf and all of the libraries underneath it are used
almost exclusively by command line clients that exit when done, so memory leaks
aren't particularly important to them.

This may break Cockpit though, since it won't be able to monitor for sysroot
changes. I considered instead running txns in a subprocess, which is possible
but harder.
  • Loading branch information
cgwalters committed Feb 4, 2017
1 parent 4f0be52 commit ea0bb53
Showing 1 changed file with 55 additions and 0 deletions.
55 changes: 55 additions & 0 deletions src/daemon/rpmostreed-daemon.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
#include "rpmostreed-utils.h"

#include <libglnx.h>
#include <stdio.h>
#include <systemd/sd-journal.h>

/**
* SECTION: daemon
Expand All @@ -50,6 +52,8 @@ struct _RpmostreedDaemon {
gint64 last_message;
guint ticker_id;

GSource *idle_exit_source;

GMutex mutex;
gint num_tasks;

Expand Down Expand Up @@ -171,6 +175,54 @@ rpmostreed_daemon_init (RpmostreedDaemon *self)
g_mutex_init (&self->mutex);
}

static gboolean
on_idle_exit (gpointer user_data)
{
sd_journal_print (LOG_INFO, "Exiting due to idle");
exit (0);
}

static void
on_active_txn_changed (GObject *object,
GParamSpec *pspec,
gpointer user_data)
{
RpmostreedDaemon *self = user_data;
g_autoptr(GVariant) active_txn = NULL;
gboolean have_active_txn = FALSE;

g_object_get (object, "active-transaction", &active_txn, NULL);

if (active_txn)
{
const char *a, *b, *c;
g_variant_get (active_txn, "(&s&s&s)", &a, &b, &c);
if (*a)
have_active_txn = TRUE;
}

if (have_active_txn)
{
if (self->idle_exit_source)
{
g_source_destroy (self->idle_exit_source);
g_clear_pointer (&self->idle_exit_source, (GDestroyNotify)g_source_unref);
}
}
else
{
if (!self->idle_exit_source)
{
/* I think adding some randomness is a good idea, to mitigate
* pathological cases where someone is talking to us at the same
* frequency as our exit timer. */
self->idle_exit_source = g_timeout_source_new_seconds (10 + g_random_int_range (0, 5));
g_source_set_callback (self->idle_exit_source, on_idle_exit, self, NULL);
g_source_attach (self->idle_exit_source, NULL);
}
}
}

static gboolean
rpmostreed_daemon_initable_init (GInitable *initable,
GCancellable *cancellable,
Expand All @@ -196,6 +248,9 @@ rpmostreed_daemon_initable_init (GInitable *initable,
goto out;
}

g_signal_connect (rpmostreed_sysroot_get (), "notify::active-transaction",
G_CALLBACK (on_active_txn_changed), self);

rpmostreed_daemon_publish (self, path, FALSE, self->sysroot);
g_dbus_connection_start_message_processing (self->connection);

Expand Down

0 comments on commit ea0bb53

Please sign in to comment.