applications: Make async file operations cancellable
The previous operations could crash if the panel was changed during an operation.
This commit is contained in:
parent
a3db60a24b
commit
3565216b5b
3 changed files with 78 additions and 13 deletions
|
@ -1221,10 +1221,16 @@ set_cache_size (GObject *source,
|
||||||
{
|
{
|
||||||
CcApplicationsPanel *self = data;
|
CcApplicationsPanel *self = data;
|
||||||
g_autofree gchar *formatted_size = NULL;
|
g_autofree gchar *formatted_size = NULL;
|
||||||
guint64 *size;
|
guint64 size;
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
|
|
||||||
size = g_object_get_data (G_OBJECT (res), "size");
|
if (!file_size_finish (G_FILE (source), res, &size, &error))
|
||||||
self->cache_size = *size;
|
{
|
||||||
|
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||||
|
g_warning ("Failed to get flatpak cache size: %s", error->message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self->cache_size = size;
|
||||||
|
|
||||||
formatted_size = g_format_size (self->cache_size);
|
formatted_size = g_format_size (self->cache_size);
|
||||||
g_object_set (self->cache, "info", formatted_size, NULL);
|
g_object_set (self->cache, "info", formatted_size, NULL);
|
||||||
|
@ -1240,7 +1246,7 @@ update_cache_row (CcApplicationsPanel *self,
|
||||||
{
|
{
|
||||||
g_autoptr(GFile) dir = get_flatpak_app_dir (app_id, "cache");
|
g_autoptr(GFile) dir = get_flatpak_app_dir (app_id, "cache");
|
||||||
g_object_set (self->cache, "info", "...", NULL);
|
g_object_set (self->cache, "info", "...", NULL);
|
||||||
file_size_async (dir, set_cache_size, self);
|
file_size_async (dir, self->cancellable, set_cache_size, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1250,10 +1256,16 @@ set_data_size (GObject *source,
|
||||||
{
|
{
|
||||||
CcApplicationsPanel *self = data;
|
CcApplicationsPanel *self = data;
|
||||||
g_autofree gchar *formatted_size = NULL;
|
g_autofree gchar *formatted_size = NULL;
|
||||||
guint64 *size;
|
guint64 size;
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
|
|
||||||
size = g_object_get_data (G_OBJECT (res), "size");
|
if (!file_size_finish (G_FILE (source), res, &size, &error))
|
||||||
self->data_size = *size;
|
{
|
||||||
|
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||||
|
g_warning ("Failed to get flatpak data size: %s", error->message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self->data_size = size;
|
||||||
|
|
||||||
formatted_size = g_format_size (self->data_size);
|
formatted_size = g_format_size (self->data_size);
|
||||||
g_object_set (self->data, "info", formatted_size, NULL);
|
g_object_set (self->data, "info", formatted_size, NULL);
|
||||||
|
@ -1268,7 +1280,7 @@ update_data_row (CcApplicationsPanel *self,
|
||||||
g_autoptr(GFile) dir = get_flatpak_app_dir (app_id, "data");
|
g_autoptr(GFile) dir = get_flatpak_app_dir (app_id, "data");
|
||||||
|
|
||||||
g_object_set (self->data, "info", "...", NULL);
|
g_object_set (self->data, "info", "...", NULL);
|
||||||
file_size_async (dir, set_data_size, self);
|
file_size_async (dir, self->cancellable, set_data_size, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1277,6 +1289,14 @@ cache_cleared (GObject *source,
|
||||||
gpointer data)
|
gpointer data)
|
||||||
{
|
{
|
||||||
CcApplicationsPanel *self = data;
|
CcApplicationsPanel *self = data;
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
|
|
||||||
|
if (!file_remove_finish (G_FILE (source), res, &error))
|
||||||
|
{
|
||||||
|
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||||
|
g_warning ("Failed to remove cache: %s", error->message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
update_cache_row (self, self->current_app_id);
|
update_cache_row (self, self->current_app_id);
|
||||||
}
|
}
|
||||||
|
@ -1290,7 +1310,7 @@ clear_cache_cb (CcApplicationsPanel *self)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
dir = get_flatpak_app_dir (self->current_app_id, "cache");
|
dir = get_flatpak_app_dir (self->current_app_id, "cache");
|
||||||
file_remove_async (dir, cache_cleared, self);
|
file_remove_async (dir, self->cancellable, cache_cleared, self);
|
||||||
}
|
}
|
||||||
static void
|
static void
|
||||||
update_app_row (CcApplicationsPanel *self,
|
update_app_row (CcApplicationsPanel *self,
|
||||||
|
|
|
@ -51,17 +51,31 @@ file_remove_thread_func (GTask *task,
|
||||||
g_autofree gchar *path = g_file_get_path (file);
|
g_autofree gchar *path = g_file_get_path (file);
|
||||||
|
|
||||||
nftw (path, ftw_remove_cb, 20, FTW_DEPTH);
|
nftw (path, ftw_remove_cb, 20, FTW_DEPTH);
|
||||||
|
|
||||||
|
if (g_task_set_return_on_cancel (task, FALSE))
|
||||||
|
g_task_return_boolean (task, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
file_remove_async (GFile *file,
|
file_remove_async (GFile *file,
|
||||||
|
GCancellable *cancellable,
|
||||||
GAsyncReadyCallback callback,
|
GAsyncReadyCallback callback,
|
||||||
gpointer data)
|
gpointer data)
|
||||||
{
|
{
|
||||||
g_autoptr(GTask) task = g_task_new (file, NULL, callback, data);
|
g_autoptr(GTask) task = g_task_new (file, cancellable, callback, data);
|
||||||
|
g_task_set_return_on_cancel (task, TRUE);
|
||||||
g_task_run_in_thread (task, file_remove_thread_func);
|
g_task_run_in_thread (task, file_remove_thread_func);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
file_remove_finish (GFile *file,
|
||||||
|
GAsyncResult *result,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (g_task_is_valid (result, file), FALSE);
|
||||||
|
return g_task_propagate_boolean (G_TASK (result), error);
|
||||||
|
}
|
||||||
|
|
||||||
static GPrivate size_key = G_PRIVATE_INIT (g_free);
|
static GPrivate size_key = G_PRIVATE_INIT (g_free);
|
||||||
|
|
||||||
static gint
|
static gint
|
||||||
|
@ -93,18 +107,38 @@ file_size_thread_func (GTask *task,
|
||||||
total = g_new0 (guint64, 1);
|
total = g_new0 (guint64, 1);
|
||||||
*total = *(guint64*)g_private_get (&size_key);
|
*total = *(guint64*)g_private_get (&size_key);
|
||||||
|
|
||||||
g_object_set_data_full (G_OBJECT (task), "size", total, g_free);
|
if (g_task_set_return_on_cancel (task, FALSE))
|
||||||
|
g_task_return_pointer (task, total, g_free);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
file_size_async (GFile *file,
|
file_size_async (GFile *file,
|
||||||
|
GCancellable *cancellable,
|
||||||
GAsyncReadyCallback callback,
|
GAsyncReadyCallback callback,
|
||||||
gpointer data)
|
gpointer data)
|
||||||
{
|
{
|
||||||
g_autoptr(GTask) task = g_task_new (file, NULL, callback, data);
|
g_autoptr(GTask) task = g_task_new (file, cancellable, callback, data);
|
||||||
|
g_task_set_return_on_cancel (task, TRUE);
|
||||||
g_task_run_in_thread (task, file_size_thread_func);
|
g_task_run_in_thread (task, file_size_thread_func);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
file_size_finish (GFile *file,
|
||||||
|
GAsyncResult *result,
|
||||||
|
guint64 *size,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
g_autofree guint64 *data = NULL;
|
||||||
|
|
||||||
|
g_return_val_if_fail (g_task_is_valid (result, file), FALSE);
|
||||||
|
data = g_task_propagate_pointer (G_TASK (result), error);
|
||||||
|
if (data == NULL)
|
||||||
|
return FALSE;
|
||||||
|
if (size != NULL)
|
||||||
|
*size = *data;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
container_remove_all (GtkContainer *container)
|
container_remove_all (GtkContainer *container)
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,13 +26,24 @@
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
void file_remove_async (GFile *file,
|
void file_remove_async (GFile *file,
|
||||||
|
GCancellable *cancellable,
|
||||||
GAsyncReadyCallback callback,
|
GAsyncReadyCallback callback,
|
||||||
gpointer data);
|
gpointer data);
|
||||||
|
|
||||||
|
gboolean file_remove_finish (GFile *file,
|
||||||
|
GAsyncResult *result,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
void file_size_async (GFile *file,
|
void file_size_async (GFile *file,
|
||||||
|
GCancellable *cancellable,
|
||||||
GAsyncReadyCallback callback,
|
GAsyncReadyCallback callback,
|
||||||
gpointer data);
|
gpointer data);
|
||||||
|
|
||||||
|
gboolean file_size_finish (GFile *file,
|
||||||
|
GAsyncResult *result,
|
||||||
|
guint64 *size,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
void container_remove_all (GtkContainer *container);
|
void container_remove_all (GtkContainer *container);
|
||||||
|
|
||||||
GKeyFile* get_flatpak_metadata (const gchar *app_id);
|
GKeyFile* get_flatpak_metadata (const gchar *app_id);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue