mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-23 04:36:17 +01:00
gibaseinfo: Allow gi_base_info_clear() to be idempotent
When called on an already-cleared `GIBaseInfo` it should do nothing. Signed-off-by: Philip Withnall <pwithnall@gnome.org> Fixes: #3255
This commit is contained in:
parent
48e3fa1e17
commit
ec9a73a262
@ -443,7 +443,9 @@ gi_info_init (GIRealInfo *info,
|
|||||||
* Clears memory allocated internally by a stack-allocated
|
* Clears memory allocated internally by a stack-allocated
|
||||||
* [type@GIRepository.BaseInfo].
|
* [type@GIRepository.BaseInfo].
|
||||||
*
|
*
|
||||||
* This does not deallocate the [type@GIRepository.BaseInfo] struct itself.
|
* This does not deallocate the [type@GIRepository.BaseInfo] struct itself. It
|
||||||
|
* does clear the struct to zero so that calling this function subsequent times
|
||||||
|
* on the same struct is a no-op.
|
||||||
*
|
*
|
||||||
* This must only be called on stack-allocated [type@GIRepository.BaseInfo]s.
|
* This must only be called on stack-allocated [type@GIRepository.BaseInfo]s.
|
||||||
* Use [method@GIRepository.BaseInfo.unref] for heap-allocated ones.
|
* Use [method@GIRepository.BaseInfo.unref] for heap-allocated ones.
|
||||||
@ -455,6 +457,11 @@ gi_base_info_clear (void *info)
|
|||||||
{
|
{
|
||||||
GIBaseInfo *rinfo = (GIBaseInfo *) info;
|
GIBaseInfo *rinfo = (GIBaseInfo *) info;
|
||||||
|
|
||||||
|
/* If @info is zero-filled, do nothing. This allows gi_base_info_clear() to be
|
||||||
|
* used with g_auto(). */
|
||||||
|
if (rinfo->ref_count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
g_return_if_fail (GI_IS_BASE_INFO (rinfo));
|
g_return_if_fail (GI_IS_BASE_INFO (rinfo));
|
||||||
|
|
||||||
g_assert (rinfo->ref_count == INVALID_REFCOUNT);
|
g_assert (rinfo->ref_count == INVALID_REFCOUNT);
|
||||||
@ -462,6 +469,8 @@ gi_base_info_clear (void *info)
|
|||||||
GI_BASE_INFO_GET_CLASS (info)->finalize (rinfo);
|
GI_BASE_INFO_GET_CLASS (info)->finalize (rinfo);
|
||||||
|
|
||||||
g_type_class_unref (rinfo->parent_instance.g_class);
|
g_type_class_unref (rinfo->parent_instance.g_class);
|
||||||
|
|
||||||
|
memset (rinfo, 0, sizeof (*rinfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
GIBaseInfo *
|
GIBaseInfo *
|
||||||
|
@ -156,6 +156,42 @@ test_repository_dependencies (RepositoryFixture *fx,
|
|||||||
g_clear_pointer (&dependencies, g_strfreev);
|
g_clear_pointer (&dependencies, g_strfreev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_repository_base_info_clear (RepositoryFixture *fx,
|
||||||
|
const void *unused)
|
||||||
|
{
|
||||||
|
GITypeInfo zeroed_type_info = { 0, };
|
||||||
|
GITypeInfo idempotent_type_info;
|
||||||
|
GIObjectInfo *object_info = NULL;
|
||||||
|
GIFunctionInfo *method_info = NULL;
|
||||||
|
GIArgInfo *arg_info = NULL;
|
||||||
|
|
||||||
|
g_test_summary ("Test calling gi_base_info_clear() on a zero-filled struct");
|
||||||
|
|
||||||
|
/* Load a valid #GITypeInfo onto the stack and clear it multiple times to
|
||||||
|
* check gi_base_info_clear() is idempotent after the first call. */
|
||||||
|
object_info = GI_OBJECT_INFO (gi_repository_find_by_name (fx->repository, "GObject", "Object"));
|
||||||
|
g_assert_nonnull (object_info);
|
||||||
|
method_info = gi_object_info_find_method (object_info, "get_property");
|
||||||
|
g_assert_nonnull (method_info);
|
||||||
|
arg_info = gi_callable_info_get_arg (GI_CALLABLE_INFO (method_info), 0);
|
||||||
|
g_assert_nonnull (arg_info);
|
||||||
|
gi_arg_info_load_type_info (arg_info, &idempotent_type_info);
|
||||||
|
|
||||||
|
gi_base_info_clear (&idempotent_type_info);
|
||||||
|
gi_base_info_clear (&idempotent_type_info);
|
||||||
|
gi_base_info_clear (&idempotent_type_info);
|
||||||
|
|
||||||
|
g_clear_pointer (&arg_info, gi_base_info_unref);
|
||||||
|
g_clear_pointer (&method_info, gi_base_info_unref);
|
||||||
|
g_clear_pointer (&object_info, gi_base_info_unref);
|
||||||
|
|
||||||
|
/* Try clearing a #GITypeInfo which has always been zero-filled on the stack. */
|
||||||
|
gi_base_info_clear (&zeroed_type_info);
|
||||||
|
gi_base_info_clear (&zeroed_type_info);
|
||||||
|
gi_base_info_clear (&zeroed_type_info);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_repository_arg_info (RepositoryFixture *fx,
|
test_repository_arg_info (RepositoryFixture *fx,
|
||||||
const void *unused)
|
const void *unused)
|
||||||
@ -750,6 +786,7 @@ main (int argc,
|
|||||||
ADD_REPOSITORY_TEST ("/repository/basic", test_repository_basic, &typelib_load_spec_glib);
|
ADD_REPOSITORY_TEST ("/repository/basic", test_repository_basic, &typelib_load_spec_glib);
|
||||||
ADD_REPOSITORY_TEST ("/repository/info", test_repository_info, &typelib_load_spec_gobject);
|
ADD_REPOSITORY_TEST ("/repository/info", test_repository_info, &typelib_load_spec_gobject);
|
||||||
ADD_REPOSITORY_TEST ("/repository/dependencies", test_repository_dependencies, &typelib_load_spec_gobject);
|
ADD_REPOSITORY_TEST ("/repository/dependencies", test_repository_dependencies, &typelib_load_spec_gobject);
|
||||||
|
ADD_REPOSITORY_TEST ("/repository/base-info/clear", test_repository_base_info_clear, &typelib_load_spec_gobject);
|
||||||
ADD_REPOSITORY_TEST ("/repository/arg-info", test_repository_arg_info, &typelib_load_spec_gobject);
|
ADD_REPOSITORY_TEST ("/repository/arg-info", test_repository_arg_info, &typelib_load_spec_gobject);
|
||||||
ADD_REPOSITORY_TEST ("/repository/callable-info", test_repository_callable_info, &typelib_load_spec_gobject);
|
ADD_REPOSITORY_TEST ("/repository/callable-info", test_repository_callable_info, &typelib_load_spec_gobject);
|
||||||
ADD_REPOSITORY_TEST ("/repository/callback-info", test_repository_callback_info, &typelib_load_spec_gobject);
|
ADD_REPOSITORY_TEST ("/repository/callback-info", test_repository_callback_info, &typelib_load_spec_gobject);
|
||||||
|
Loading…
Reference in New Issue
Block a user