From 85ce99f4ad52c435e1198a76d8cac6feeb34ff72 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Thu, 12 Sep 2024 10:26:05 -0400 Subject: [PATCH] gio: Add a query_exists vfunc to GFile g_file_query_exists looks like a simpler and faster api than g_file_query_info. This vfunc lets us actually make it faster, and avoid allocations in this frequently used code path. --- gio/gfile.c | 15 ++++++++++++--- gio/gfile.h | 4 ++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/gio/gfile.c b/gio/gfile.c index 5ac73c03e..6f104459f 100644 --- a/gio/gfile.c +++ b/gio/gfile.c @@ -1192,8 +1192,11 @@ g_file_enumerate_children_finish (GFile *file, * @cancellable: (nullable): optional #GCancellable object, * %NULL to ignore * - * Utility function to check if a particular file exists. This is - * implemented using g_file_query_info() and as such does blocking I/O. + * Utility function to check if a particular file exists. + * + * The fallback implementation of this API is using [method@Gio.File.query_info] + * and therefore may do blocking I/O. To asynchronously query the existence + * of a file, use [method@Gio.File.query_info_async]. * * Note that in many cases it is [racy to first check for file existence](https://en.wikipedia.org/wiki/Time_of_check_to_time_of_use) * and then execute something based on the outcome of that, because the @@ -1222,9 +1225,15 @@ gboolean g_file_query_exists (GFile *file, GCancellable *cancellable) { + GFileIface *iface; GFileInfo *info; - g_return_val_if_fail (G_IS_FILE(file), FALSE); + g_return_val_if_fail (G_IS_FILE (file), FALSE); + + iface = G_FILE_GET_IFACE (file); + + if (iface->query_exists) + return iface->query_exists (file, cancellable); info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_TYPE, G_FILE_QUERY_INFO_NONE, cancellable, NULL); diff --git a/gio/gfile.h b/gio/gfile.h index d49c3b36c..74e50db83 100644 --- a/gio/gfile.h +++ b/gio/gfile.h @@ -148,6 +148,7 @@ typedef struct _GFileIface GFileIface; * @measure_disk_usage: Recursively measures the disk usage of @file. Since 2.38 * @measure_disk_usage_async: Asynchronously recursively measures the disk usage of @file. Since 2.38 * @measure_disk_usage_finish: Finishes an asynchronous recursive measurement of the disk usage of @file. Since 2.38 + * @query_exists: Queries whether a file exists. Since 2.84 * * An interface for writing VFS file handles. **/ @@ -598,6 +599,9 @@ struct _GFileIface guint64 *num_dirs, guint64 *num_files, GError **error); + + gboolean (* query_exists) (GFile *file, + GCancellable *cancellable); }; GIO_AVAILABLE_IN_ALL