handle_update_in_thread_func (GTask *task,
                              gpointer source_object,
                              gpointer task_data,
                              GCancellable *cancellable)
{
  PortalFlatpakUpdateMonitor *monitor = source_object;
  UpdateMonitorData *m = update_monitor_get_data (monitor);
  g_autoptr(GError) error = NULL;
  const char *window;

  window = (const char *)g_object_get_data (G_OBJECT (task), "window");

  if (request_update_permissions_sync (monitor, m->name, window, &error))
    {
      g_autoptr(GFile) installation_path = update_monitor_get_installation_path (monitor);
      g_autofree char *ref = flatpak_build_app_ref (m->name, m->branch, m->arch);
      const char *argv[] = { "/proc/self/exe", "flatpak-portal", "--update", flatpak_file_get_path_cached (installation_path), ref, NULL };
      int sockets[2];
      GPid pid;

      if (socketpair (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sockets) != 0)
        {
          glnx_throw_errno (&error);
        }
      else
        {
          gboolean spawn_ok;

          spawn_ok = g_spawn_async (NULL, (char **)argv, NULL,
                                    G_SPAWN_FILE_AND_ARGV_ZERO |
                                    G_SPAWN_LEAVE_DESCRIPTORS_OPEN,
                                    update_child_setup_func, &sockets[1],
                                    &pid, &error);
          close (sockets[1]); // Close remote side
          if (spawn_ok)
            {
              if (!handle_update_responses (monitor, sockets[0], &error))
                {
                  if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
                    kill (pid, SIGINT);
                }
            }
          close (sockets[0]); // Close local side
        }
    }

  if (error)
    emit_progress_error (monitor, error);

  g_mutex_lock (&m->lock);
  m->installing = FALSE;
  g_mutex_unlock (&m->lock);
}
handle_update_in_thread_func (GTask *task,
                              gpointer source_object,
                              gpointer task_data,
                              GCancellable *cancellable)
{
  PortalFlatpakUpdateMonitor *monitor = source_object;
  UpdateMonitorData *m = update_monitor_get_data (monitor);
  g_autoptr(GError) error = NULL;
  const char *window;

  window = (const char *)g_object_get_data (G_OBJECT (task), "window");

  if (request_update_permissions_sync (monitor, m->name, window, &error))
    {
      g_autoptr(GFile) installation_path = update_monitor_get_installation_path (monitor);
      g_autofree char *ref = flatpak_build_app_ref (m->name, m->branch, m->arch);
      const char *argv[] = { "/proc/self/exe", "flatpak-portal", "--update", flatpak_file_get_path_cached (installation_path), ref, NULL };
      int sockets[2];
      GPid pid;

      if (socketpair (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sockets) != 0)
        {
          glnx_throw_errno (&error);
        }
      else
        {
          gboolean spawn_ok;

          spawn_ok = g_spawn_async (NULL, (char **)argv, NULL,
                                    G_SPAWN_FILE_AND_ARGV_ZERO |
                                    G_SPAWN_LEAVE_DESCRIPTORS_OPEN,
                                    update_child_setup_func, &sockets[1],
                                    &pid, &error);
          close (sockets[1]);  
          if (spawn_ok)
            {
              if (!handle_update_responses (monitor, sockets[0], &error))
                {
                  if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
                    kill (pid, SIGINT);
                }
            }
          close (sockets[0]);  
        }
    }

  if (error)
    emit_progress_error (monitor, error);

  g_mutex_lock (&m->lock);
  m->installing = FALSE;
  g_mutex_unlock (&m->lock);
}