mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-23 04:36:17 +01:00
gitypelib: Switch to refcounting
Since `GITypelib` is exposed in the public libgirepository API, it needs to be a boxed type. So we either need to add a `copy` method to mirror the existing `free` method, or switch to refcounting. The latter option seems better, since a `GITypelib` contains internal state about open `GModule`s and the semantics for copying that would be potentially complex. Signed-off-by: Philip Withnall <pwithnall@gnome.org> Helps: #3155
This commit is contained in:
parent
702719dee9
commit
5cc5f413f5
@ -71,6 +71,7 @@ your code if integer type warnings are enabled.
|
||||
| `g_type_info_get_array_length` and `g_type_info_get_array_fixed_size` | Split success and failure return values out into a new out-argument and return value |
|
||||
| `g_type_info_get_array_length` | [method@GIRepository.TypeInfo.get_array_length_index] |
|
||||
| `g_typelib_new_from_*` | All replaced with `gi_typelib_new_from_bytes()` |
|
||||
| `g_typelib_free` | [type@GIRepository.Typelib] is now a refcounted and boxed type, so use [method@GIRepository.Typelib.unref] |
|
||||
| `GI_FUNCTION_THROWS` and `GI_VFUNC_THROWS` | [method@GIRepository.CallableInfo.can_throw_gerror] |
|
||||
| `g_union_info_get_copy_function` | [method@GIRepository.UnionInfo.get_copy_function_name] |
|
||||
| `g_union_info_get_free_function` | [method@GIRepository.UnionInfo.get_free_function_name] |
|
||||
|
@ -218,7 +218,7 @@ main (int argc, char **argv)
|
||||
g_debug ("[building] start");
|
||||
|
||||
{
|
||||
GITypelib *typelib;
|
||||
GITypelib *typelib = NULL;
|
||||
|
||||
if (shlibs)
|
||||
{
|
||||
@ -238,8 +238,8 @@ main (int argc, char **argv)
|
||||
|
||||
if (!write_out_typelib (NULL, typelib))
|
||||
return 1;
|
||||
gi_typelib_free (typelib);
|
||||
typelib = NULL;
|
||||
|
||||
g_clear_pointer (&typelib, gi_typelib_unref);
|
||||
}
|
||||
|
||||
g_debug ("[building] done");
|
||||
|
@ -185,11 +185,11 @@ gi_repository_init (GIRepository *repository)
|
||||
repository->typelibs
|
||||
= g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
(GDestroyNotify) g_free,
|
||||
(GDestroyNotify) gi_typelib_free);
|
||||
(GDestroyNotify) gi_typelib_unref);
|
||||
repository->lazy_typelibs
|
||||
= g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
(GDestroyNotify) g_free,
|
||||
(GDestroyNotify) NULL);
|
||||
(GDestroyNotify) gi_typelib_unref);
|
||||
repository->info_by_gtype
|
||||
= g_hash_table_new_full (g_direct_hash, g_direct_equal,
|
||||
(GDestroyNotify) NULL,
|
||||
@ -513,7 +513,7 @@ register_internal (GIRepository *repository,
|
||||
g_assert (!g_hash_table_lookup (repository->lazy_typelibs,
|
||||
namespace));
|
||||
g_hash_table_insert (repository->lazy_typelibs,
|
||||
build_typelib_key (namespace, source), (void *)typelib);
|
||||
build_typelib_key (namespace, source), gi_typelib_ref (typelib));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -534,7 +534,7 @@ register_internal (GIRepository *repository,
|
||||
|
||||
g_hash_table_insert (repository->typelibs,
|
||||
g_steal_pointer (&key),
|
||||
(void *)typelib);
|
||||
gi_typelib_ref (typelib));
|
||||
}
|
||||
|
||||
/* These types might be resolved now, clear the cache */
|
||||
@ -685,7 +685,7 @@ gi_repository_get_dependencies (GIRepository *repository,
|
||||
/**
|
||||
* gi_repository_load_typelib:
|
||||
* @repository: A #GIRepository
|
||||
* @typelib: the typelib to load
|
||||
* @typelib: (transfer none): the typelib to load
|
||||
* @flags: flags affecting the loading operation
|
||||
* @error: return location for a [type@GLib.Error], or `NULL`
|
||||
*
|
||||
@ -1706,6 +1706,7 @@ require_internal (GIRepository *repository,
|
||||
GITypelib *ret = NULL;
|
||||
Header *header;
|
||||
GITypelib *typelib = NULL;
|
||||
GITypelib *typelib_owned = NULL;
|
||||
const char *typelib_namespace, *typelib_version;
|
||||
gboolean allow_lazy = (flags & GI_REPOSITORY_LOAD_FLAG_LAZY) > 0;
|
||||
gboolean is_lazy;
|
||||
@ -1762,7 +1763,7 @@ require_internal (GIRepository *repository,
|
||||
GBytes *bytes = NULL;
|
||||
|
||||
bytes = g_mapped_file_get_bytes (mfile);
|
||||
typelib = gi_typelib_new_from_bytes (bytes, &temp_error);
|
||||
typelib_owned = typelib = gi_typelib_new_from_bytes (bytes, &temp_error);
|
||||
g_bytes_unref (bytes);
|
||||
g_clear_pointer (&mfile, g_mapped_file_unref);
|
||||
|
||||
@ -1789,7 +1790,6 @@ require_internal (GIRepository *repository,
|
||||
"Typelib file %s for namespace '%s' contains "
|
||||
"namespace '%s' which doesn't match the file name",
|
||||
path, namespace, typelib_namespace);
|
||||
gi_typelib_free (typelib);
|
||||
goto out;
|
||||
}
|
||||
if (version != NULL && strcmp (typelib_version, version) != 0)
|
||||
@ -1799,18 +1799,15 @@ require_internal (GIRepository *repository,
|
||||
"Typelib file %s for namespace '%s' contains "
|
||||
"version '%s' which doesn't match the expected version '%s'",
|
||||
path, namespace, typelib_version, version);
|
||||
gi_typelib_free (typelib);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!register_internal (repository, path, allow_lazy,
|
||||
typelib, error))
|
||||
{
|
||||
gi_typelib_free (typelib);
|
||||
goto out;
|
||||
}
|
||||
goto out;
|
||||
ret = typelib;
|
||||
out:
|
||||
g_clear_pointer (&typelib_owned, gi_typelib_unref);
|
||||
g_free (tmp_version);
|
||||
g_free (path);
|
||||
return ret;
|
||||
|
@ -1313,6 +1313,7 @@ typedef struct {
|
||||
|
||||
struct _GITypelib {
|
||||
/*< private >*/
|
||||
gatomicrefcount ref_count;
|
||||
const uint8_t *data; /* just a cached pointer to inside @bytes */
|
||||
size_t len;
|
||||
GBytes *bytes; /* (owned) */
|
||||
|
@ -2353,6 +2353,7 @@ gi_typelib_new_from_bytes (GBytes *bytes,
|
||||
return NULL;
|
||||
|
||||
meta = g_slice_new0 (GITypelib);
|
||||
g_atomic_ref_count_init (&meta->ref_count);
|
||||
meta->bytes = g_bytes_ref (bytes);
|
||||
meta->data = data;
|
||||
meta->len = len;
|
||||
@ -2362,26 +2363,52 @@ gi_typelib_new_from_bytes (GBytes *bytes,
|
||||
}
|
||||
|
||||
/**
|
||||
* gi_typelib_free:
|
||||
* gi_typelib_ref:
|
||||
* @typelib: (transfer none): a #GITypelib
|
||||
*
|
||||
* Increment the reference count of a [type@GIRepository.Typelib].
|
||||
*
|
||||
* Returns: (transfer full): the same @typelib pointer
|
||||
* Since: 2.80
|
||||
*/
|
||||
GITypelib *
|
||||
gi_typelib_ref (GITypelib *typelib)
|
||||
{
|
||||
g_return_val_if_fail (typelib != NULL, NULL);
|
||||
|
||||
g_atomic_ref_count_inc (&typelib->ref_count);
|
||||
|
||||
return typelib;
|
||||
}
|
||||
|
||||
/**
|
||||
* gi_typelib_unref:
|
||||
* @typelib: (transfer full): a #GITypelib
|
||||
*
|
||||
* Free a [type@GIRepository.Typelib].
|
||||
* Decrement the reference count of a [type@GIRepository.Typelib].
|
||||
*
|
||||
* Once the reference count reaches zero, the typelib is freed.
|
||||
*
|
||||
* Since: 2.80
|
||||
*/
|
||||
void
|
||||
gi_typelib_free (GITypelib *typelib)
|
||||
gi_typelib_unref (GITypelib *typelib)
|
||||
{
|
||||
g_clear_pointer (&typelib->bytes, g_bytes_unref);
|
||||
g_return_if_fail (typelib != NULL);
|
||||
|
||||
g_clear_pointer (&typelib->library_paths, g_ptr_array_unref);
|
||||
|
||||
if (typelib->modules)
|
||||
if (g_atomic_ref_count_dec (&typelib->ref_count))
|
||||
{
|
||||
g_list_foreach (typelib->modules, (GFunc) (void *) g_module_close, NULL);
|
||||
g_list_free (typelib->modules);
|
||||
g_clear_pointer (&typelib->bytes, g_bytes_unref);
|
||||
|
||||
g_clear_pointer (&typelib->library_paths, g_ptr_array_unref);
|
||||
|
||||
if (typelib->modules)
|
||||
{
|
||||
g_list_foreach (typelib->modules, (GFunc) (void *) g_module_close, NULL);
|
||||
g_list_free (typelib->modules);
|
||||
}
|
||||
g_slice_free (GITypelib, typelib);
|
||||
}
|
||||
g_slice_free (GITypelib, typelib);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -41,7 +41,9 @@ GITypelib * gi_typelib_new_from_bytes (GBytes *bytes,
|
||||
GError **error);
|
||||
|
||||
GI_AVAILABLE_IN_ALL
|
||||
void gi_typelib_free (GITypelib *typelib);
|
||||
GITypelib * gi_typelib_ref (GITypelib *typelib);
|
||||
GI_AVAILABLE_IN_ALL
|
||||
void gi_typelib_unref (GITypelib *typelib);
|
||||
|
||||
GI_AVAILABLE_IN_ALL
|
||||
gboolean gi_typelib_symbol (GITypelib *typelib,
|
||||
|
Loading…
Reference in New Issue
Block a user