From 447a4a3824129e2eb9e0397b73fee6ce3be13256 Mon Sep 17 00:00:00 2001
From: Simon McVittie <smcv@collabora.com>
Date: Fri, 19 Feb 2021 11:14:28 +0000
Subject: [PATCH] runtime: Delay garbage-collection a bit

If we want to delete outdated temporary deployment directories such as
deploy-soldier_x.y.z, then we have to wait until we have decided which
one is current, so we can avoid deleting that one.

Signed-off-by: Simon McVittie <smcv@collabora.com>
---
 pressure-vessel/runtime.c | 47 ++++++++++++++++++++-------------------
 1 file changed, 24 insertions(+), 23 deletions(-)

diff --git a/pressure-vessel/runtime.c b/pressure-vessel/runtime.c
index fa7cfb688..0b7a7a745 100644
--- a/pressure-vessel/runtime.c
+++ b/pressure-vessel/runtime.c
@@ -673,29 +673,6 @@ pv_runtime_init_variable_dir (PvRuntime *self,
                        &self->variable_dir_fd, error))
     return FALSE;
 
-  /* GC old runtimes (if they have become unused) before we create a
-   * new one. This means we should only ever have one temporary runtime
-   * copy per game that is run concurrently. */
-  if (self->flags & PV_RUNTIME_FLAGS_GC_RUNTIMES)
-    {
-      g_autoptr(PvBwrapLock) mutable_lock = NULL;
-      g_autoptr(GError) local_error = NULL;
-
-      /* Take out an exclusive lock for GC so that we will not conflict
-       * with other concurrent processes that are halfway through
-       * deploying or unpacking a runtime. */
-      mutable_lock = pv_bwrap_lock_new (self->variable_dir_fd, ".ref",
-                                        (PV_BWRAP_LOCK_FLAGS_CREATE
-                                         | PV_BWRAP_LOCK_FLAGS_WRITE),
-                                        &local_error);
-
-      if (mutable_lock == NULL)
-        g_debug ("Unable to take an exclusive lock, skipping GC: %s",
-                 local_error->message);
-      else if (!pv_runtime_garbage_collect (self, mutable_lock, error))
-        return FALSE;
-    }
-
   return TRUE;
 }
 
@@ -1102,6 +1079,30 @@ pv_runtime_initable_init (GInitable *initable,
   if (self->runtime_lock == NULL)
     return FALSE;
 
+  /* GC old runtimes (if they have become unused) before we create a
+   * new one. This means we should only ever have one temporary runtime
+   * copy per game that is run concurrently. */
+  if (self->variable_dir_fd >= 0
+      && (self->flags & PV_RUNTIME_FLAGS_GC_RUNTIMES))
+    {
+      g_autoptr(GError) local_error = NULL;
+
+      /* Take out an exclusive lock for GC so that we will not conflict
+       * with other concurrent processes that are halfway through
+       * deploying or unpacking a runtime. */
+      if (mutable_lock == NULL)
+        mutable_lock = pv_bwrap_lock_new (self->variable_dir_fd, ".ref",
+                                          (PV_BWRAP_LOCK_FLAGS_CREATE
+                                           | PV_BWRAP_LOCK_FLAGS_WRITE),
+                                          &local_error);
+
+      if (mutable_lock == NULL)
+        g_debug ("Unable to take an exclusive lock, skipping GC: %s",
+                 local_error->message);
+      else if (!pv_runtime_garbage_collect (self, mutable_lock, error))
+        return FALSE;
+    }
+
   if (self->flags & PV_RUNTIME_FLAGS_COPY_RUNTIME)
     {
       if (self->variable_dir_fd < 0)
-- 
GitLab