From 4c791f49e58688d1b8948d083c1780cab9d26e93 Mon Sep 17 00:00:00 2001 From: Ryan Lortie Date: Thu, 18 Jun 2009 15:00:01 -0400 Subject: [PATCH] GMappedFile: add refcounting, switch to GSlice - add g_mapped_file_ref() and g_mapped_file_unref(). - deprecate g_mapped_file_free(). - move to GSlice for allocating the GMappedFile struct. --- docs/reference/glib/glib-sections.txt | 2 + glib/glib.symbols | 4 ++ glib/gmappedfile.c | 73 ++++++++++++++++++++++++++++------- glib/gmappedfile.h | 5 +++ 4 files changed, 71 insertions(+), 13 deletions(-) diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt index 55370c2..b947841 100644 --- a/docs/reference/glib/glib-sections.txt +++ b/docs/reference/glib/glib-sections.txt @@ -1114,6 +1114,8 @@ g_dir_close GMappedFile g_mapped_file_new +g_mapped_file_ref +g_mapped_file_unref g_mapped_file_free g_mapped_file_get_length g_mapped_file_get_contents diff --git a/glib/glib.symbols b/glib/glib.symbols index a1d9c9e..8bcd899 100644 --- a/glib/glib.symbols +++ b/glib/glib.symbols @@ -683,9 +683,13 @@ g_timeout_source_new_seconds g_mapped_file_new G_GNUC_MALLOC g_mapped_file_get_length g_mapped_file_get_contents +g_mapped_file_ref +g_mapped_file_unref +#ifndef G_DISABLE_DEPRECATED g_mapped_file_free #endif #endif +#endif #if IN_HEADER(__G_MARKUP_H__) #if IN_FILE(__G_MARKUP_C__) diff --git a/glib/gmappedfile.c b/glib/gmappedfile.c index dc83491..77865b8 100644 --- a/glib/gmappedfile.c +++ b/glib/gmappedfile.c @@ -52,6 +52,7 @@ #include "gmessages.h" #include "gstdio.h" #include "gstrfuncs.h" +#include "gatomic.h" #include "glibintl.h" @@ -69,6 +70,7 @@ struct _GMappedFile { gsize length; gchar *contents; + int ref_count; #ifdef G_OS_WIN32 HANDLE mapping; #endif @@ -92,8 +94,8 @@ struct _GMappedFile * will not be modified, or if all modifications of the file are done * atomically (e.g. using g_file_set_contents()). * - * Return value: a newly allocated #GMappedFile which must be freed - * with g_mapped_file_free(), or %NULL if the mapping failed. + * Return value: a newly allocated #GMappedFile which must be unref'd + * with g_mapped_file_unref(), or %NULL if the mapping failed. * * Since: 2.8 */ @@ -125,7 +127,8 @@ g_mapped_file_new (const gchar *filename, return NULL; } - file = g_new0 (GMappedFile, 1); + file = g_slice_new0 (GMappedFile); + file->ref_count = 1; if (fstat (fd, &st) == -1) { @@ -207,7 +210,7 @@ g_mapped_file_new (const gchar *filename, out: close (fd); - g_free (file); + g_slice_free (GMappedFile, file); return NULL; } @@ -255,29 +258,73 @@ g_mapped_file_get_contents (GMappedFile *file) * g_mapped_file_free: * @file: a #GMappedFile * - * Unmaps the buffer of @file and frees it. + * This call existed before #GMappedFile had refcounting and is currently + * exactly the same as g_mapped_file_unref(). * * Since: 2.8 + * Deprecated:2.22: Use g_mapped_file_unref() instead. */ void g_mapped_file_free (GMappedFile *file) { + g_mapped_file_unref (file); +} + +/** + * g_mapped_file_ref: + * @file: a #GMappedFile + * + * Increments the reference count of @file by one. It is safe to call + * this function from any thread. + * + * Return value: the passed in #GMappedFile. + * + * Since: 2.22 + **/ +GMappedFile * +g_mapped_file_ref (GMappedFile *file) +{ + g_return_val_if_fail (file != NULL, NULL); + g_return_val_if_fail (file->ref_count > 0, file); + + g_atomic_int_inc (&file->ref_count); + + return file; +} + +/** + * g_mapped_file_unref: + * @file: a #GMappedFile + * + * Decrements the reference count of @file by one. If the reference count + * drops to 0, unmaps the buffer of @file and frees it. + * + * It is safe to call this function from any thread. + * + * Since 2.22 + **/ +void +g_mapped_file_unref (GMappedFile *file) +{ g_return_if_fail (file != NULL); + g_return_if_fail (file->ref_count > 0); - if (file->length) - { + if (g_atomic_int_dec_and_test (&file->ref_count)) + { + if (file->length) + { #ifdef HAVE_MMAP - munmap (file->contents, file->length); + munmap (file->contents, file->length); #endif #ifdef G_OS_WIN32 - UnmapViewOfFile (file->contents); - CloseHandle (file->mapping); + UnmapViewOfFile (file->contents); + CloseHandle (file->mapping); #endif - } + } - g_free (file); + g_slice_free (GMappedFile, file); + } } - #define __G_MAPPED_FILE_C__ #include "galiasdef.c" diff --git a/glib/gmappedfile.h b/glib/gmappedfile.h index d27c4aa..dbb3f89 100644 --- a/glib/gmappedfile.h +++ b/glib/gmappedfile.h @@ -37,7 +37,12 @@ GMappedFile *g_mapped_file_new (const gchar *filename, GError **error) G_GNUC_MALLOC; gsize g_mapped_file_get_length (GMappedFile *file); gchar *g_mapped_file_get_contents (GMappedFile *file); +GMappedFile *g_mapped_file_ref (GMappedFile *file); +void g_mapped_file_unref (GMappedFile *file); + +#ifndef G_DISABLE_DEPRECATED void g_mapped_file_free (GMappedFile *file); +#endif G_END_DECLS -- 2.7.4