mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-25 06:56:14 +01:00
Merge branch 'migrate-to-gi-docgen12' into 'main'
gdir, gstrvbuilder: Add refcounting support and a boxed type See merge request GNOME/glib!3722
This commit is contained in:
commit
e4fe837bae
100
glib/gdir.c
100
glib/gdir.c
@ -56,6 +56,7 @@
|
||||
|
||||
struct _GDir
|
||||
{
|
||||
gatomicrefcount ref_count;
|
||||
#ifdef G_OS_WIN32
|
||||
_WDIR *wdirp;
|
||||
#else
|
||||
@ -89,10 +90,13 @@ GDir *
|
||||
g_dir_open_with_errno (const gchar *path,
|
||||
guint flags)
|
||||
{
|
||||
GDir dir;
|
||||
#ifdef G_OS_WIN32
|
||||
GDir *dir;
|
||||
_WDIR *wdirp;
|
||||
gint saved_errno;
|
||||
wchar_t *wpath;
|
||||
#else
|
||||
DIR *dirp;
|
||||
#endif
|
||||
|
||||
g_return_val_if_fail (path != NULL, NULL);
|
||||
@ -102,21 +106,27 @@ g_dir_open_with_errno (const gchar *path,
|
||||
|
||||
g_return_val_if_fail (wpath != NULL, NULL);
|
||||
|
||||
dir.wdirp = _wopendir (wpath);
|
||||
wdirp = _wopendir (wpath);
|
||||
saved_errno = errno;
|
||||
g_free (wpath);
|
||||
errno = saved_errno;
|
||||
|
||||
if (dir.wdirp == NULL)
|
||||
if (wdirp == NULL)
|
||||
return NULL;
|
||||
|
||||
dir = g_new0 (GDir, 1);
|
||||
g_atomic_ref_count_init (&dir->ref_count);
|
||||
dir->wdirp = wdirp;
|
||||
|
||||
return g_steal_pointer (&dir);
|
||||
#else
|
||||
dir.dirp = opendir (path);
|
||||
dirp = opendir (path);
|
||||
|
||||
if (dir.dirp == NULL)
|
||||
if (dirp == NULL)
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
return g_memdup2 (&dir, sizeof dir);
|
||||
return g_dir_new_from_dirp (dirp);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@ -187,7 +197,8 @@ g_dir_new_from_dirp (gpointer dirp)
|
||||
|
||||
g_return_val_if_fail (dirp != NULL, NULL);
|
||||
|
||||
dir = g_new (GDir, 1);
|
||||
dir = g_new0 (GDir, 1);
|
||||
g_atomic_ref_count_init (&dir->ref_count);
|
||||
dir->dirp = dirp;
|
||||
|
||||
return dir;
|
||||
@ -287,24 +298,85 @@ g_dir_rewind (GDir *dir)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
g_dir_actually_close (GDir *dir)
|
||||
{
|
||||
#ifdef G_OS_WIN32
|
||||
g_clear_pointer (&dir->wdirp, _wclosedir);
|
||||
#else
|
||||
g_clear_pointer (&dir->dirp, closedir);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* g_dir_close:
|
||||
* @dir: (transfer full): a #GDir* created by g_dir_open()
|
||||
*
|
||||
* Closes the directory and deallocates all related resources.
|
||||
* Closes the directory immediately and decrements the reference count.
|
||||
*
|
||||
* Once the reference count reaches zero, the `GDir` structure itself will be
|
||||
* freed. Prior to GLib 2.80, `GDir` was not reference counted.
|
||||
*
|
||||
* It is an error to call any of the `GDir` methods other than
|
||||
* [method@GLib.Dir.ref] and [method@GLib.Dir.unref] on a `GDir` after calling
|
||||
* [method@GLib.Dir.close] on it.
|
||||
**/
|
||||
void
|
||||
g_dir_close (GDir *dir)
|
||||
{
|
||||
g_return_if_fail (dir != NULL);
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
_wclosedir (dir->wdirp);
|
||||
#else
|
||||
closedir (dir->dirp);
|
||||
#endif
|
||||
g_dir_actually_close (dir);
|
||||
g_dir_unref (dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_dir_ref:
|
||||
* @dir: (transfer none): a `GDir`
|
||||
*
|
||||
* Increment the reference count of `dir`.
|
||||
*
|
||||
* Returns: (transfer full): the same pointer as `dir`
|
||||
* Since: 2.80
|
||||
*/
|
||||
GDir *
|
||||
g_dir_ref (GDir *dir)
|
||||
{
|
||||
g_return_val_if_fail (dir != NULL, NULL);
|
||||
|
||||
g_atomic_ref_count_inc (&dir->ref_count);
|
||||
return dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* g_dir_unref:
|
||||
* @dir: (transfer full): a `GDir`
|
||||
*
|
||||
* Decrements the reference count of `dir`.
|
||||
*
|
||||
* Once the reference count reaches zero, the directory will be closed and all
|
||||
* resources associated with it will be freed. If [method@GLib.Dir.close] is
|
||||
* called when the reference count is greater than zero, the directory is closed
|
||||
* but the `GDir` structure will not be freed until its reference count reaches
|
||||
* zero.
|
||||
*
|
||||
* It is an error to call any of the `GDir` methods other than
|
||||
* [method@GLib.Dir.ref] and [method@GLib.Dir.unref] on a `GDir` after calling
|
||||
* [method@GLib.Dir.close] on it.
|
||||
*
|
||||
* Since: 2.80
|
||||
*/
|
||||
void
|
||||
g_dir_unref (GDir *dir)
|
||||
{
|
||||
g_return_if_fail (dir != NULL);
|
||||
|
||||
if (g_atomic_ref_count_dec (&dir->ref_count))
|
||||
{
|
||||
g_dir_actually_close (dir);
|
||||
g_free (dir);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
|
||||
|
@ -49,6 +49,11 @@ void g_dir_rewind (GDir *dir);
|
||||
GLIB_AVAILABLE_IN_ALL
|
||||
void g_dir_close (GDir *dir);
|
||||
|
||||
GLIB_AVAILABLE_IN_2_80
|
||||
GDir * g_dir_ref (GDir *dir);
|
||||
GLIB_AVAILABLE_IN_2_80
|
||||
void g_dir_unref (GDir *dir);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __G_DIR_H__ */
|
||||
|
@ -57,7 +57,7 @@ typedef struct stat GStatBuf;
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(G_OS_UNIX) && !defined(G_STDIO_WRAP_ON_UNIX)
|
||||
#if defined(G_OS_UNIX) && !defined(G_STDIO_WRAP_ON_UNIX) && !defined(__GI_SCANNER__)
|
||||
|
||||
/* Just pass on to the system functions, so there's no potential for data
|
||||
* format mismatches, especially with large file interfaces.
|
||||
|
@ -41,6 +41,29 @@ test_dir_nonexisting (void)
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
static void
|
||||
test_dir_refcounting (void)
|
||||
{
|
||||
GDir *dir;
|
||||
GError *local_error = NULL;
|
||||
|
||||
g_test_summary ("Test refcounting interactions with g_dir_close()");
|
||||
|
||||
/* Try keeping the `GDir` struct alive after closing it. */
|
||||
dir = g_dir_open (".", 0, &local_error);
|
||||
g_assert_no_error (local_error);
|
||||
|
||||
g_dir_ref (dir);
|
||||
g_dir_close (dir);
|
||||
g_dir_unref (dir);
|
||||
|
||||
/* Test that dropping the last ref closes it. Any leak here should be caught
|
||||
* when the test is run under valgrind. */
|
||||
dir = g_dir_open (".", 0, &local_error);
|
||||
g_assert_no_error (local_error);
|
||||
g_dir_unref (dir);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
@ -48,6 +71,7 @@ main (int argc, char *argv[])
|
||||
|
||||
g_test_add_func ("/dir/read", test_dir_read);
|
||||
g_test_add_func ("/dir/nonexisting", test_dir_nonexisting);
|
||||
g_test_add_func ("/dir/refcounting", test_dir_refcounting);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
@ -139,6 +139,7 @@ G_DEFINE_BOXED_TYPE (GKeyFile, g_key_file, g_key_file_ref, g_key_file_unref)
|
||||
G_DEFINE_BOXED_TYPE (GMappedFile, g_mapped_file, g_mapped_file_ref, g_mapped_file_unref)
|
||||
G_DEFINE_BOXED_TYPE (GBookmarkFile, g_bookmark_file, g_bookmark_file_copy, g_bookmark_file_free)
|
||||
G_DEFINE_BOXED_TYPE (GHmac, g_hmac, g_hmac_ref, g_hmac_unref)
|
||||
G_DEFINE_BOXED_TYPE (GDir, g_dir, g_dir_ref, g_dir_unref)
|
||||
|
||||
G_DEFINE_BOXED_TYPE (GMainLoop, g_main_loop, g_main_loop_ref, g_main_loop_unref)
|
||||
G_DEFINE_BOXED_TYPE (GMainContext, g_main_context, g_main_context_ref, g_main_context_unref)
|
||||
@ -153,6 +154,8 @@ G_DEFINE_BOXED_TYPE (GUri, g_uri, g_uri_ref, g_uri_unref)
|
||||
G_DEFINE_BOXED_TYPE (GOptionGroup, g_option_group, g_option_group_ref, g_option_group_unref)
|
||||
G_DEFINE_BOXED_TYPE (GPatternSpec, g_pattern_spec, g_pattern_spec_copy, g_pattern_spec_free);
|
||||
|
||||
G_DEFINE_BOXED_TYPE (GStrvBuilder, g_strv_builder, g_strv_builder_ref, g_strv_builder_unref);
|
||||
|
||||
/* This one can't use G_DEFINE_BOXED_TYPE (GStrv, g_strv, g_strdupv, g_strfreev) */
|
||||
GType
|
||||
g_strv_get_type (void)
|
||||
|
@ -345,6 +345,24 @@ typedef gsize GType;
|
||||
*/
|
||||
#define G_TYPE_HMAC (g_hmac_get_type ())
|
||||
|
||||
/**
|
||||
* G_TYPE_DIR:
|
||||
*
|
||||
* The #GType for a boxed type holding a #GDir.
|
||||
*
|
||||
* Since: 2.80
|
||||
*/
|
||||
#define G_TYPE_DIR (g_dir_get_type ())
|
||||
|
||||
/**
|
||||
* G_TYPE_STRV_BUILDER:
|
||||
*
|
||||
* The #GType for a boxed type holding a #GStrvBuilder.
|
||||
*
|
||||
* Since: 2.80
|
||||
*/
|
||||
#define G_TYPE_STRV_BUILDER (g_strv_builder_get_type ())
|
||||
|
||||
GOBJECT_AVAILABLE_IN_ALL
|
||||
GType g_date_get_type (void) G_GNUC_CONST;
|
||||
GOBJECT_AVAILABLE_IN_ALL
|
||||
@ -411,6 +429,10 @@ GOBJECT_AVAILABLE_IN_2_76
|
||||
GType g_bookmark_file_get_type (void) G_GNUC_CONST;
|
||||
GOBJECT_AVAILABLE_IN_2_80
|
||||
GType g_hmac_get_type (void) G_GNUC_CONST;
|
||||
GOBJECT_AVAILABLE_IN_2_80
|
||||
GType g_dir_get_type (void) G_GNUC_CONST;
|
||||
GOBJECT_AVAILABLE_IN_2_80
|
||||
GType g_strv_builder_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GOBJECT_DEPRECATED_FOR('G_TYPE_VARIANT')
|
||||
GType g_variant_get_gtype (void) G_GNUC_CONST;
|
||||
|
Loading…
Reference in New Issue
Block a user