From 4eb856da4e356157fad52e10e504a176beb7159e Mon Sep 17 00:00:00 2001 From: DistroBaker Date: Tue, 24 Nov 2020 13:15:04 +0000 Subject: [PATCH] Merged update from upstream sources This is an automated DistroBaker update from upstream sources. If you do not know what this is about or would like to opt out, contact the OSCI team. Source: https://src.fedoraproject.org/rpms/glib2.git#f9fbe5a4c84a5e8bd24f76f82128fa2de8da15ac --- 1719.patch | 3417 ++++++++++++++++++++++++++++++++++++++++++++++++++++ glib2.spec | 10 +- 2 files changed, 3426 insertions(+), 1 deletion(-) create mode 100644 1719.patch diff --git a/1719.patch b/1719.patch new file mode 100644 index 0000000..bbdaa2c --- /dev/null +++ b/1719.patch @@ -0,0 +1,3417 @@ +From fab561f8d05794329184cd81f9ab9d9d77dcc22a Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Wed, 11 Nov 2020 18:12:22 +0000 +Subject: [PATCH 01/29] gobject: Drop use of volatile from get_type() macros +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +http://isvolatileusefulwiththreads.in/c/ + +It’s possible that the variables here are only marked as volatile +because they’re arguments to `g_once_*()`. Those arguments will be +modified in a subsequent commit. + +Signed-off-by: Philip Withnall + +Helps: #600 +--- + docs/reference/gobject/glib-mkenums.xml | 8 ++--- + docs/reference/gobject/tut_gtype.xml | 2 +- + gio/gioenumtypes.c.template | 8 ++--- + gio/tests/gsettings.c | 4 +-- + gobject/gbinding.c | 8 ++--- + gobject/gboxed.c | 8 ++--- + gobject/glib-enumtypes.c.template | 8 ++--- + gobject/gsourceclosure.c | 2 +- + gobject/gtype.h | 48 ++++++++++++------------- + gobject/tests/signals.c | 16 ++++----- + 10 files changed, 56 insertions(+), 56 deletions(-) + +diff --git a/docs/reference/gobject/glib-mkenums.xml b/docs/reference/gobject/glib-mkenums.xml +index 2200328ed..ce250a3ff 100644 +--- a/docs/reference/gobject/glib-mkenums.xml ++++ b/docs/reference/gobject/glib-mkenums.xml +@@ -480,9 +480,9 @@ A C source template file will typically look like this: + GType + @enum_name@_get_type (void) + { +- static volatile gsize g_@type@_type_id__volatile; ++ static gsize static_g_@type@_type_id; + +- if (g_once_init_enter (&g_define_type_id__volatile)) ++ if (g_once_init_enter (&static_g_@type@_type_id)) + { + static const G@Type@Value values[] = { + /*** END value-header ***/ +@@ -498,9 +498,9 @@ GType + GType g_@type@_type_id = + g_@type@_register_static (g_intern_static_string ("@EnumName@"), values); + +- g_once_init_leave (&g_@type@_type_id__volatile, g_@type@_type_id); ++ g_once_init_leave (&static_g_@type@_type_id, g_@type@_type_id); + } +- return g_@type@_type_id__volatile; ++ return static_g_@type@_type_id; + } + + /*** END value-tail ***/ +diff --git a/docs/reference/gobject/tut_gtype.xml b/docs/reference/gobject/tut_gtype.xml +index 25e37dc48..ee042889d 100644 +--- a/docs/reference/gobject/tut_gtype.xml ++++ b/docs/reference/gobject/tut_gtype.xml +@@ -852,7 +852,7 @@ viewer_editable_default_init (ViewerEditableInterface *iface) + GType + viewer_editable_get_type (void) + { +- static volatile gsize type_id = 0; ++ static gsize type_id = 0; + if (g_once_init_enter (&type_id)) { + const GTypeInfo info = { + sizeof (ViewerEditableInterface), +diff --git a/gio/gioenumtypes.c.template b/gio/gioenumtypes.c.template +index e9adc4a38..948a01201 100644 +--- a/gio/gioenumtypes.c.template ++++ b/gio/gioenumtypes.c.template +@@ -13,9 +13,9 @@ + GType + @enum_name@_get_type (void) + { +- static volatile gsize g_define_type_id__volatile = 0; ++ static gsize static_g_define_type_id = 0; + +- if (g_once_init_enter (&g_define_type_id__volatile)) ++ if (g_once_init_enter (&static_g_define_type_id)) + { + static const G@Type@Value values[] = { + /*** END value-header ***/ +@@ -29,10 +29,10 @@ GType + }; + GType g_define_type_id = + g_@type@_register_static (g_intern_static_string ("@EnumName@"), values); +- g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); ++ g_once_init_leave (&static_g_define_type_id, g_define_type_id); + } + +- return g_define_type_id__volatile; ++ return static_g_define_type_id; + } + + /*** END value-tail ***/ +diff --git a/gio/tests/gsettings.c b/gio/tests/gsettings.c +index 2f81ae6c3..179d0fd2f 100644 +--- a/gio/tests/gsettings.c ++++ b/gio/tests/gsettings.c +@@ -1060,7 +1060,7 @@ test_object_set_property (GObject *object, + static GType + test_enum_get_type (void) + { +- static volatile gsize define_type_id = 0; ++ static gsize define_type_id = 0; + + if (g_once_init_enter (&define_type_id)) + { +@@ -1082,7 +1082,7 @@ test_enum_get_type (void) + static GType + test_flags_get_type (void) + { +- static volatile gsize define_type_id = 0; ++ static gsize define_type_id = 0; + + if (g_once_init_enter (&define_type_id)) + { +diff --git a/gobject/gbinding.c b/gobject/gbinding.c +index 78a883075..662d76b3c 100644 +--- a/gobject/gbinding.c ++++ b/gobject/gbinding.c +@@ -120,9 +120,9 @@ + GType + g_binding_flags_get_type (void) + { +- static volatile gsize g_define_type_id__volatile = 0; ++ static gsize static_g_define_type_id = 0; + +- if (g_once_init_enter (&g_define_type_id__volatile)) ++ if (g_once_init_enter (&static_g_define_type_id)) + { + static const GFlagsValue values[] = { + { G_BINDING_DEFAULT, "G_BINDING_DEFAULT", "default" }, +@@ -133,10 +133,10 @@ g_binding_flags_get_type (void) + }; + GType g_define_type_id = + g_flags_register_static (g_intern_static_string ("GBindingFlags"), values); +- g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); ++ g_once_init_leave (&static_g_define_type_id, g_define_type_id); + } + +- return g_define_type_id__volatile; ++ return static_g_define_type_id; + } + + #define G_BINDING_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), G_TYPE_BINDING, GBindingClass)) +diff --git a/gobject/gboxed.c b/gobject/gboxed.c +index 30ba4e775..194251383 100644 +--- a/gobject/gboxed.c ++++ b/gobject/gboxed.c +@@ -180,19 +180,19 @@ G_DEFINE_BOXED_TYPE (GOptionGroup, g_option_group, g_option_group_ref, g_option_ + GType + g_strv_get_type (void) + { +- static volatile gsize g_define_type_id__volatile = 0; ++ static gsize static_g_define_type_id = 0; + +- if (g_once_init_enter (&g_define_type_id__volatile)) ++ if (g_once_init_enter (&static_g_define_type_id)) + { + GType g_define_type_id = + g_boxed_type_register_static (g_intern_static_string ("GStrv"), + (GBoxedCopyFunc) g_strdupv, + (GBoxedFreeFunc) g_strfreev); + +- g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); ++ g_once_init_leave (&static_g_define_type_id, g_define_type_id); + } + +- return g_define_type_id__volatile; ++ return static_g_define_type_id; + } + + GType +diff --git a/gobject/glib-enumtypes.c.template b/gobject/glib-enumtypes.c.template +index b7d36728f..1800ca8af 100644 +--- a/gobject/glib-enumtypes.c.template ++++ b/gobject/glib-enumtypes.c.template +@@ -13,9 +13,9 @@ + GType + @enum_name@_get_type (void) + { +- static volatile gsize g_define_type_id__volatile = 0; ++ static gsize static_g_define_type_id = 0; + +- if (g_once_init_enter (&g_define_type_id__volatile)) ++ if (g_once_init_enter (&static_g_define_type_id)) + { + static const G@Type@Value values[] = { + /*** END value-header ***/ +@@ -29,10 +29,10 @@ GType + }; + GType g_define_type_id = + g_@type@_register_static (g_intern_static_string ("@EnumName@"), values); +- g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); ++ g_once_init_leave (&static_g_define_type_id, g_define_type_id); + } + +- return g_define_type_id__volatile; ++ return static_g_define_type_id; + } + + /*** END value-tail ***/ +diff --git a/gobject/gsourceclosure.c b/gobject/gsourceclosure.c +index 0d0d2e87c..d1b1ee4b3 100644 +--- a/gobject/gsourceclosure.c ++++ b/gobject/gsourceclosure.c +@@ -32,7 +32,7 @@ G_DEFINE_BOXED_TYPE (GIOChannel, g_io_channel, g_io_channel_ref, g_io_channel_un + GType + g_io_condition_get_type (void) + { +- static volatile GType etype = 0; ++ static GType etype = 0; + + if (g_once_init_enter (&etype)) + { +diff --git a/gobject/gtype.h b/gobject/gtype.h +index 9de46ac60..666fadb0c 100644 +--- a/gobject/gtype.h ++++ b/gobject/gtype.h +@@ -1727,8 +1727,8 @@ guint g_type_get_type_registration_serial (void); + * GType + * gtk_gadget_get_type (void) + * { +- * static volatile gsize g_define_type_id__volatile = 0; +- * if (g_once_init_enter (&g_define_type_id__volatile)) ++ * static gsize static_g_define_type_id = 0; ++ * if (g_once_init_enter (&static_g_define_type_id)) + * { + * GType g_define_type_id = + * g_type_register_static_simple (GTK_TYPE_WIDGET, +@@ -1748,9 +1748,9 @@ guint g_type_get_type_registration_serial (void); + * }; + * g_type_add_interface_static (g_define_type_id, TYPE_GIZMO, &g_implement_interface_info); + * } +- * g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); ++ * g_once_init_leave (&static_g_define_type_id, g_define_type_id); + * } +- * return g_define_type_id__volatile; ++ * return static_g_define_type_id; + * } + * ]| + * The only pieces which have to be manually provided are the definitions of +@@ -1995,17 +1995,17 @@ type_name##_get_instance_private (TypeName *self) \ + GType \ + type_name##_get_type (void) \ + { \ +- static volatile gsize g_define_type_id__volatile = 0; ++ static gsize static_g_define_type_id = 0; + /* Prelude goes here */ + + /* Added for _G_DEFINE_TYPE_EXTENDED_WITH_PRELUDE */ + #define _G_DEFINE_TYPE_EXTENDED_BEGIN_REGISTER(TypeName, type_name, TYPE_PARENT, flags) \ +- if (g_once_init_enter (&g_define_type_id__volatile)) \ ++ if (g_once_init_enter (&static_g_define_type_id)) \ + { \ + GType g_define_type_id = type_name##_get_type_once (); \ +- g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); \ ++ g_once_init_leave (&static_g_define_type_id, g_define_type_id); \ + } \ +- return g_define_type_id__volatile; \ ++ return static_g_define_type_id; \ + } /* closes type_name##_get_type() */ \ + \ + G_GNUC_NO_INLINE \ +@@ -2041,8 +2041,8 @@ static void type_name##_default_init (TypeName##Interface *klass); \ + GType \ + type_name##_get_type (void) \ + { \ +- static volatile gsize g_define_type_id__volatile = 0; \ +- if (g_once_init_enter (&g_define_type_id__volatile)) \ ++ static gsize static_g_define_type_id = 0; \ ++ if (g_once_init_enter (&static_g_define_type_id)) \ + { \ + GType g_define_type_id = \ + g_type_register_static_simple (G_TYPE_INTERFACE, \ +@@ -2058,9 +2058,9 @@ type_name##_get_type (void) \ + #define _G_DEFINE_INTERFACE_EXTENDED_END() \ + /* following custom code */ \ + } \ +- g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); \ ++ g_once_init_leave (&static_g_define_type_id, g_define_type_id); \ + } \ +- return g_define_type_id__volatile; \ ++ return static_g_define_type_id; \ + } /* closes type_name##_get_type() */ + + /** +@@ -2115,13 +2115,13 @@ static GType type_name##_get_type_once (void); \ + GType \ + type_name##_get_type (void) \ + { \ +- static volatile gsize g_define_type_id__volatile = 0; \ +- if (g_once_init_enter (&g_define_type_id__volatile)) \ ++ static gsize static_g_define_type_id = 0; \ ++ if (g_once_init_enter (&static_g_define_type_id)) \ + { \ + GType g_define_type_id = type_name##_get_type_once (); \ +- g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); \ ++ g_once_init_leave (&static_g_define_type_id, g_define_type_id); \ + } \ +- return g_define_type_id__volatile; \ ++ return static_g_define_type_id; \ + } \ + \ + G_GNUC_NO_INLINE \ +@@ -2152,13 +2152,13 @@ static GType type_name##_get_type_once (void); \ + GType \ + type_name##_get_type (void) \ + { \ +- static volatile gsize g_define_type_id__volatile = 0; \ +- if (g_once_init_enter (&g_define_type_id__volatile)) \ ++ static gsize static_g_define_type_id = 0; \ ++ if (g_once_init_enter (&static_g_define_type_id)) \ + { \ + GType g_define_type_id = type_name##_get_type_once (); \ +- g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); \ ++ g_once_init_leave (&static_g_define_type_id, g_define_type_id); \ + } \ +- return g_define_type_id__volatile; \ ++ return static_g_define_type_id; \ + } \ + \ + G_GNUC_NO_INLINE \ +@@ -2205,13 +2205,13 @@ static GType type_name##_get_type_once (void); \ + GType \ + type_name##_get_type (void) \ + { \ +- static volatile gsize g_define_type_id__volatile = 0; \ +- if (g_once_init_enter (&g_define_type_id__volatile)) \ ++ static gsize static_g_define_type_id = 0; \ ++ if (g_once_init_enter (&static_g_define_type_id)) \ + { \ + GType g_define_type_id = type_name##_get_type_once (); \ +- g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); \ ++ g_once_init_leave (&static_g_define_type_id, g_define_type_id); \ + } \ +- return g_define_type_id__volatile; \ ++ return static_g_define_type_id; \ + } \ + \ + G_GNUC_NO_INLINE \ +diff --git a/gobject/tests/signals.c b/gobject/tests/signals.c +index 120f90b5c..ac0ce5102 100644 +--- a/gobject/tests/signals.c ++++ b/gobject/tests/signals.c +@@ -66,9 +66,9 @@ custom_marshal_VOID__INVOCATIONHINT (GClosure *closure, + static GType + test_enum_get_type (void) + { +- static volatile gsize g_define_type_id__volatile = 0; ++ static gsize static_g_define_type_id = 0; + +- if (g_once_init_enter (&g_define_type_id__volatile)) ++ if (g_once_init_enter (&static_g_define_type_id)) + { + static const GEnumValue values[] = { + { TEST_ENUM_NEGATIVE, "TEST_ENUM_NEGATIVE", "negative" }, +@@ -79,18 +79,18 @@ test_enum_get_type (void) + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("TestEnum"), values); +- g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); ++ g_once_init_leave (&static_g_define_type_id, g_define_type_id); + } + +- return g_define_type_id__volatile; ++ return static_g_define_type_id; + } + + static GType + test_unsigned_enum_get_type (void) + { +- static volatile gsize g_define_type_id__volatile = 0; ++ static gsize static_g_define_type_id = 0; + +- if (g_once_init_enter (&g_define_type_id__volatile)) ++ if (g_once_init_enter (&static_g_define_type_id)) + { + static const GEnumValue values[] = { + { TEST_UNSIGNED_ENUM_FOO, "TEST_UNSIGNED_ENUM_FOO", "foo" }, +@@ -99,10 +99,10 @@ test_unsigned_enum_get_type (void) + }; + GType g_define_type_id = + g_enum_register_static (g_intern_static_string ("TestUnsignedEnum"), values); +- g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); ++ g_once_init_leave (&static_g_define_type_id, g_define_type_id); + } + +- return g_define_type_id__volatile; ++ return static_g_define_type_id; + } + + typedef enum { +-- +GitLab + + +From a6ce0e742a5c75c53a7c702ebb1af1084065160a Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Wed, 11 Nov 2020 18:14:29 +0000 +Subject: [PATCH 02/29] tests: Fix non-atomic access to a shared variable +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +And drop the `volatile` qualifier from the variable, as that doesn’t +help with thread safety. + +Signed-off-by: Philip Withnall + +Helps: #600 +--- + glib/tests/642026.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/glib/tests/642026.c b/glib/tests/642026.c +index ef54f14bb..26ab2ed06 100644 +--- a/glib/tests/642026.c ++++ b/glib/tests/642026.c +@@ -25,7 +25,7 @@ static GMutex *mutex; + static GCond *cond; + static guint i; + +-static volatile gint freed = 0; ++static gint freed = 0; /* (atomic) */ + + static void + notify (gpointer p) +@@ -63,7 +63,7 @@ testcase (void) + GThread *t1; + + g_static_private_init (&sp); +- freed = 0; ++ g_atomic_int_set (&freed, 0); + + t1 = g_thread_create (thread_func, NULL, TRUE, NULL); + g_assert (t1 != NULL); +-- +GitLab + + +From ea746c79faf554d980c21b0e4381753e003d2dc6 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Wed, 11 Nov 2020 18:17:23 +0000 +Subject: [PATCH 03/29] tests: Fix non-atomic access to a shared variable +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +And drop the `volatile` qualifier from the variable, as that doesn’t +help with thread safety. + +Signed-off-by: Philip Withnall + +Helps: #600 +--- + glib/tests/mainloop.c | 20 ++++++++++---------- + 1 file changed, 10 insertions(+), 10 deletions(-) + +diff --git a/glib/tests/mainloop.c b/glib/tests/mainloop.c +index 16763a0ea..563a951de 100644 +--- a/glib/tests/mainloop.c ++++ b/glib/tests/mainloop.c +@@ -918,7 +918,7 @@ test_mainloop_overflow (void) + g_main_context_unref (ctx); + } + +-static volatile gint ready_time_dispatched; ++static gint ready_time_dispatched; /* (atomic) */ + + static gboolean + ready_time_dispatch (GSource *source, +@@ -964,7 +964,7 @@ test_ready_time (void) + /* A source with no ready time set should not fire */ + g_assert_cmpint (g_source_get_ready_time (source), ==, -1); + while (g_main_context_iteration (NULL, FALSE)); +- g_assert_false (ready_time_dispatched); ++ g_assert_false (g_atomic_int_get (&ready_time_dispatched)); + + /* The ready time should not have been changed */ + g_assert_cmpint (g_source_get_ready_time (source), ==, -1); +@@ -978,37 +978,37 @@ test_ready_time (void) + */ + g_source_set_ready_time (source, g_get_monotonic_time () + G_TIME_SPAN_DAY); + while (g_main_context_iteration (NULL, FALSE)); +- g_assert_false (ready_time_dispatched); ++ g_assert_false (g_atomic_int_get (&ready_time_dispatched)); + /* Make sure it didn't get reset */ + g_assert_cmpint (g_source_get_ready_time (source), !=, -1); + + /* Ready time of -1 -> don't fire */ + g_source_set_ready_time (source, -1); + while (g_main_context_iteration (NULL, FALSE)); +- g_assert_false (ready_time_dispatched); ++ g_assert_false (g_atomic_int_get (&ready_time_dispatched)); + /* Not reset, but should still be -1 from above */ + g_assert_cmpint (g_source_get_ready_time (source), ==, -1); + + /* A ready time of the current time should fire immediately */ + g_source_set_ready_time (source, g_get_monotonic_time ()); + while (g_main_context_iteration (NULL, FALSE)); +- g_assert_true (ready_time_dispatched); +- ready_time_dispatched = FALSE; ++ g_assert_true (g_atomic_int_get (&ready_time_dispatched)); ++ g_atomic_int_set (&ready_time_dispatched, FALSE); + /* Should have gotten reset by the handler function */ + g_assert_cmpint (g_source_get_ready_time (source), ==, -1); + + /* As well as one in the recent past... */ + g_source_set_ready_time (source, g_get_monotonic_time () - G_TIME_SPAN_SECOND); + while (g_main_context_iteration (NULL, FALSE)); +- g_assert_true (ready_time_dispatched); +- ready_time_dispatched = FALSE; ++ g_assert_true (g_atomic_int_get (&ready_time_dispatched)); ++ g_atomic_int_set (&ready_time_dispatched, FALSE); + g_assert_cmpint (g_source_get_ready_time (source), ==, -1); + + /* Zero is the 'official' way to get a source to fire immediately */ + g_source_set_ready_time (source, 0); + while (g_main_context_iteration (NULL, FALSE)); +- g_assert_true (ready_time_dispatched); +- ready_time_dispatched = FALSE; ++ g_assert_true (g_atomic_int_get (&ready_time_dispatched)); ++ g_atomic_int_set (&ready_time_dispatched, FALSE); + g_assert_cmpint (g_source_get_ready_time (source), ==, -1); + + /* Now do some tests of cross-thread wakeups. +-- +GitLab + + +From 3dda662bebb81666d009635df1055ba5c1e17b52 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Wed, 11 Nov 2020 18:16:17 +0000 +Subject: [PATCH 04/29] tests: Drop unnecessary volatile qualifiers from tests +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +These variables were already (correctly) accessed atomically. The +`volatile` qualifier doesn’t help with that. + +Signed-off-by: Philip Withnall + +Helps: #600 +--- + glib/tests/atomic.c | 4 ++-- + glib/tests/cond.c | 2 +- + glib/tests/gwakeuptest.c | 2 +- + glib/tests/hash.c | 2 +- + glib/tests/slice.c | 2 +- + 5 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/glib/tests/atomic.c b/glib/tests/atomic.c +index 6b6cc7f3e..7d2459f3a 100644 +--- a/glib/tests/atomic.c ++++ b/glib/tests/atomic.c +@@ -248,8 +248,8 @@ G_GNUC_END_IGNORE_DEPRECATIONS + #define THREADS 10 + #define ROUNDS 10000 + +-volatile gint bucket[THREADS]; +-volatile gint atomic; ++gint bucket[THREADS]; /* never contested by threads, not accessed atomically */ ++gint atomic; /* (atomic) */ + + static gpointer + thread_func (gpointer data) +diff --git a/glib/tests/cond.c b/glib/tests/cond.c +index 0f0b3d249..ed338cce3 100644 +--- a/glib/tests/cond.c ++++ b/glib/tests/cond.c +@@ -29,7 +29,7 @@ + + static GCond cond; + static GMutex mutex; +-static volatile gint next; ++static gint next; /* locked by @mutex */ + + static void + push_value (gint value) +diff --git a/glib/tests/gwakeuptest.c b/glib/tests/gwakeuptest.c +index 461a7d3de..b37fb43fc 100644 +--- a/glib/tests/gwakeuptest.c ++++ b/glib/tests/gwakeuptest.c +@@ -92,7 +92,7 @@ struct context + static struct context contexts[NUM_THREADS]; + static GThread *threads[NUM_THREADS]; + static GWakeup *last_token_wakeup; +-static volatile gint tokens_alive; ++static gint tokens_alive; /* (atomic) */ + + static void + context_init (struct context *ctx) +diff --git a/glib/tests/hash.c b/glib/tests/hash.c +index 4623d18d1..f4ff55ce1 100644 +--- a/glib/tests/hash.c ++++ b/glib/tests/hash.c +@@ -1362,7 +1362,7 @@ struct _GHashTable + + GHashFunc hash_func; + GEqualFunc key_equal_func; +- volatile gint ref_count; ++ gint ref_count; /* (atomic) */ + + #ifndef G_DISABLE_ASSERT + int version; +diff --git a/glib/tests/slice.c b/glib/tests/slice.c +index f37826f3a..a566280db 100644 +--- a/glib/tests/slice.c ++++ b/glib/tests/slice.c +@@ -107,7 +107,7 @@ thread_allocate (gpointer data) + gint b; + gint size; + gpointer p; +- volatile gpointer *loc; ++ gpointer *loc; /* (atomic) */ + + for (i = 0; i < 10000; i++) + { +-- +GitLab + + +From 7f905ff1faf0acbe0d2ce69937e031fcacce9294 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Wed, 11 Nov 2020 18:21:00 +0000 +Subject: [PATCH 05/29] tests: Fix non-atomic access to some shared variables +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +And drop the `volatile` qualifier from the variables, as that doesn’t +help with thread safety. + +Signed-off-by: Philip Withnall + +Helps: #600 +--- + gio/tests/gdbus-connection-flush.c | 6 +- + gio/tests/gdbus-connection.c | 40 ++++---- + gio/tests/gdbus-overflow.c | 20 ++-- + gio/tests/socket-service.c | 6 +- + gio/tests/task.c | 150 ++++++++++++++--------------- + 5 files changed, 111 insertions(+), 111 deletions(-) + +diff --git a/gio/tests/gdbus-connection-flush.c b/gio/tests/gdbus-connection-flush.c +index 73a034b81..8c925825a 100644 +--- a/gio/tests/gdbus-connection-flush.c ++++ b/gio/tests/gdbus-connection-flush.c +@@ -43,9 +43,9 @@ G_LOCK_DEFINE_STATIC (write); + typedef struct { + GFilterOutputStream parent; + +- volatile gint started; +- volatile gint finished; +- volatile gint flushed; ++ gint started; /* (atomic) */ ++ gint finished; /* (atomic) */ ++ gint flushed; /* (atomic) */ + + GOutputStream *real_output; + } MyOutputStream; +diff --git a/gio/tests/gdbus-connection.c b/gio/tests/gdbus-connection.c +index 278570609..51dd27f7e 100644 +--- a/gio/tests/gdbus-connection.c ++++ b/gio/tests/gdbus-connection.c +@@ -61,9 +61,9 @@ _log (const gchar *format, ...) + static gboolean + test_connection_quit_mainloop (gpointer user_data) + { +- volatile gboolean *quit_mainloop_fired = user_data; ++ gboolean *quit_mainloop_fired = user_data; /* (atomic) */ + _log ("quit_mainloop_fired"); +- *quit_mainloop_fired = TRUE; ++ g_atomic_int_set (quit_mainloop_fired, TRUE); + g_main_loop_quit (loop); + return G_SOURCE_CONTINUE; + } +@@ -113,8 +113,8 @@ on_name_owner_changed (GDBusConnection *connection, + static void + a_gdestroynotify_that_sets_a_gboolean_to_true_and_quits_loop (gpointer user_data) + { +- volatile gboolean *val = user_data; +- *val = TRUE; ++ gboolean *val = user_data; /* (atomic) */ ++ g_atomic_int_set (val, TRUE); + _log ("destroynotify fired for %p", val); + g_main_loop_quit (loop); + } +@@ -143,10 +143,10 @@ test_connection_life_cycle (void) + GDBusConnection *c; + GDBusConnection *c2; + GError *error; +- volatile gboolean on_signal_registration_freed_called; +- volatile gboolean on_filter_freed_called; +- volatile gboolean on_register_object_freed_called; +- volatile gboolean quit_mainloop_fired; ++ gboolean on_signal_registration_freed_called; /* (atomic) */ ++ gboolean on_filter_freed_called; /* (atomic) */ ++ gboolean on_register_object_freed_called; /* (atomic) */ ++ gboolean quit_mainloop_fired; /* (atomic) */ + guint quit_mainloop_id; + guint registration_id; + +@@ -208,7 +208,7 @@ test_connection_life_cycle (void) + g_assert_no_error (error); + g_assert_nonnull (c2); + /* signal registration */ +- on_signal_registration_freed_called = FALSE; ++ g_atomic_int_set (&on_signal_registration_freed_called, FALSE); + g_dbus_connection_signal_subscribe (c2, + "org.freedesktop.DBus", /* bus name */ + "org.freedesktop.DBus", /* interface */ +@@ -220,13 +220,13 @@ test_connection_life_cycle (void) + (gpointer) &on_signal_registration_freed_called, + a_gdestroynotify_that_sets_a_gboolean_to_true_and_quits_loop); + /* filter func */ +- on_filter_freed_called = FALSE; ++ g_atomic_int_set (&on_filter_freed_called, FALSE); + g_dbus_connection_add_filter (c2, + some_filter_func, + (gpointer) &on_filter_freed_called, + a_gdestroynotify_that_sets_a_gboolean_to_true_and_quits_loop); + /* object registration */ +- on_register_object_freed_called = FALSE; ++ g_atomic_int_set (&on_register_object_freed_called, FALSE); + error = NULL; + registration_id = g_dbus_connection_register_object (c2, + "/foo", +@@ -239,7 +239,7 @@ test_connection_life_cycle (void) + g_assert_cmpuint (registration_id, >, 0); + /* ok, finalize the connection and check that all the GDestroyNotify functions are invoked as expected */ + g_object_unref (c2); +- quit_mainloop_fired = FALSE; ++ g_atomic_int_set (&quit_mainloop_fired, FALSE); + quit_mainloop_id = g_timeout_add (30000, test_connection_quit_mainloop, (gpointer) &quit_mainloop_fired); + _log ("destroynotifies for\n" + " register_object %p\n" +@@ -250,21 +250,21 @@ test_connection_life_cycle (void) + &on_signal_registration_freed_called); + while (TRUE) + { +- if (on_signal_registration_freed_called && +- on_filter_freed_called && +- on_register_object_freed_called) ++ if (g_atomic_int_get (&on_signal_registration_freed_called) && ++ g_atomic_int_get (&on_filter_freed_called) && ++ g_atomic_int_get (&on_register_object_freed_called)) + break; +- if (quit_mainloop_fired) ++ if (g_atomic_int_get (&quit_mainloop_fired)) + break; + _log ("entering loop"); + g_main_loop_run (loop); + _log ("exiting loop"); + } + g_source_remove (quit_mainloop_id); +- g_assert_true (on_signal_registration_freed_called); +- g_assert_true (on_filter_freed_called); +- g_assert_true (on_register_object_freed_called); +- g_assert_false (quit_mainloop_fired); ++ g_assert_true (g_atomic_int_get (&on_signal_registration_freed_called)); ++ g_assert_true (g_atomic_int_get (&on_filter_freed_called)); ++ g_assert_true (g_atomic_int_get (&on_register_object_freed_called)); ++ g_assert_false (g_atomic_int_get (&quit_mainloop_fired)); + + /* + * Check for correct behavior when the bus goes away +diff --git a/gio/tests/gdbus-overflow.c b/gio/tests/gdbus-overflow.c +index ca3d5d0e7..d3e1eb295 100644 +--- a/gio/tests/gdbus-overflow.c ++++ b/gio/tests/gdbus-overflow.c +@@ -86,8 +86,8 @@ overflow_filter_func (GDBusConnection *connection, + gboolean incoming, + gpointer user_data) + { +- volatile gint *counter = user_data; +- *counter += 1; ++ gint *counter = user_data; /* (atomic) */ ++ g_atomic_int_inc (counter); + return message; + } + +@@ -108,8 +108,8 @@ test_overflow (void) + GDBusConnection *producer, *consumer; + GError *error; + GTimer *timer; +- volatile gint n_messages_received; +- volatile gint n_messages_sent; ++ gint n_messages_received; /* (atomic) */ ++ gint n_messages_sent; /* (atomic) */ + + g_assert_cmpint (socketpair (AF_UNIX, SOCK_STREAM, 0, sv), ==, 0); + +@@ -129,7 +129,7 @@ test_overflow (void) + g_dbus_connection_set_exit_on_close (producer, TRUE); + g_assert_no_error (error); + g_object_unref (socket_connection); +- n_messages_sent = 0; ++ g_atomic_int_set (&n_messages_sent, 0); + g_dbus_connection_add_filter (producer, overflow_filter_func, (gpointer) &n_messages_sent, NULL); + + /* send enough data that we get an EAGAIN */ +@@ -155,7 +155,7 @@ test_overflow (void) + */ + g_timeout_add (500, overflow_on_500ms_later_func, NULL); + g_main_loop_run (loop); +- g_assert_cmpint (n_messages_sent, <, OVERFLOW_NUM_SIGNALS); ++ g_assert_cmpint (g_atomic_int_get (&n_messages_sent), <, OVERFLOW_NUM_SIGNALS); + + /* now suck it all out as a client, and add it up */ + socket = g_socket_new_from_fd (sv[1], &error); +@@ -171,18 +171,18 @@ test_overflow (void) + &error); + g_assert_no_error (error); + g_object_unref (socket_connection); +- n_messages_received = 0; ++ g_atomic_int_set (&n_messages_received, 0); + g_dbus_connection_add_filter (consumer, overflow_filter_func, (gpointer) &n_messages_received, NULL); + g_dbus_connection_start_message_processing (consumer); + + timer = g_timer_new (); + g_timer_start (timer); + +- while (n_messages_received < OVERFLOW_NUM_SIGNALS && g_timer_elapsed (timer, NULL) < OVERFLOW_TIMEOUT_SEC) ++ while (g_atomic_int_get (&n_messages_received) < OVERFLOW_NUM_SIGNALS && g_timer_elapsed (timer, NULL) < OVERFLOW_TIMEOUT_SEC) + g_main_context_iteration (NULL, FALSE); + +- g_assert_cmpint (n_messages_sent, ==, OVERFLOW_NUM_SIGNALS); +- g_assert_cmpint (n_messages_received, ==, OVERFLOW_NUM_SIGNALS); ++ g_assert_cmpint (g_atomic_int_get (&n_messages_sent), ==, OVERFLOW_NUM_SIGNALS); ++ g_assert_cmpint (g_atomic_int_get (&n_messages_received), ==, OVERFLOW_NUM_SIGNALS); + + g_timer_destroy (timer); + g_object_unref (consumer); +diff --git a/gio/tests/socket-service.c b/gio/tests/socket-service.c +index f1dd783d1..8487a700e 100644 +--- a/gio/tests/socket-service.c ++++ b/gio/tests/socket-service.c +@@ -99,7 +99,7 @@ test_start_stop (void) + + GMutex mutex_712570; + GCond cond_712570; +-volatile gboolean finalized; ++gboolean finalized; /* (atomic) */ + + GType test_threaded_socket_service_get_type (void); + typedef GThreadedSocketService TestThreadedSocketService; +@@ -120,7 +120,7 @@ test_threaded_socket_service_finalize (GObject *object) + /* Signal the main thread that finalization completed successfully + * rather than hanging. + */ +- finalized = TRUE; ++ g_atomic_int_set (&finalized, TRUE); + g_cond_signal (&cond_712570); + g_mutex_unlock (&mutex_712570); + } +@@ -235,7 +235,7 @@ test_threaded_712570 (void) + */ + g_object_unref (service); + +- while (!finalized) ++ while (!g_atomic_int_get (&finalized)) + g_cond_wait (&cond_712570, &mutex_712570); + g_mutex_unlock (&mutex_712570); + } +diff --git a/gio/tests/task.c b/gio/tests/task.c +index cca05ced1..7ce8438ff 100644 +--- a/gio/tests/task.c ++++ b/gio/tests/task.c +@@ -957,7 +957,7 @@ task_weak_notify (gpointer user_data, + gboolean *weak_notify_ran = user_data; + + g_mutex_lock (&run_in_thread_mutex); +- *weak_notify_ran = TRUE; ++ g_atomic_int_set (weak_notify_ran, TRUE); + g_cond_signal (&run_in_thread_cond); + g_mutex_unlock (&run_in_thread_mutex); + } +@@ -1007,7 +1007,7 @@ run_in_thread_thread (GTask *task, + g_assert (g_thread_self () != main_thread); + + g_mutex_lock (&run_in_thread_mutex); +- *thread_ran = TRUE; ++ g_atomic_int_set (thread_ran, TRUE); + g_cond_signal (&run_in_thread_cond); + g_mutex_unlock (&run_in_thread_mutex); + +@@ -1018,8 +1018,8 @@ static void + test_run_in_thread (void) + { + GTask *task; +- volatile gboolean thread_ran = FALSE; +- volatile gboolean weak_notify_ran = FALSE; ++ gboolean thread_ran = FALSE; /* (atomic) */ ++ gboolean weak_notify_ran = FALSE; /* (atomic) */ + gboolean notification_emitted = FALSE; + gboolean done = FALSE; + +@@ -1033,12 +1033,12 @@ test_run_in_thread (void) + g_task_run_in_thread (task, run_in_thread_thread); + + g_mutex_lock (&run_in_thread_mutex); +- while (!thread_ran) ++ while (!g_atomic_int_get (&thread_ran)) + g_cond_wait (&run_in_thread_cond, &run_in_thread_mutex); + g_mutex_unlock (&run_in_thread_mutex); + + g_assert (done == FALSE); +- g_assert (weak_notify_ran == FALSE); ++ g_assert_false (g_atomic_int_get (&weak_notify_ran)); + + g_main_loop_run (loop); + +@@ -1050,7 +1050,7 @@ test_run_in_thread (void) + g_object_unref (task); + + g_mutex_lock (&run_in_thread_mutex); +- while (!weak_notify_ran) ++ while (!g_atomic_int_get (&weak_notify_ran)) + g_cond_wait (&run_in_thread_cond, &run_in_thread_mutex); + g_mutex_unlock (&run_in_thread_mutex); + } +@@ -1081,7 +1081,7 @@ run_in_thread_sync_thread (GTask *task, + + g_assert (g_thread_self () != main_thread); + +- *thread_ran = TRUE; ++ g_atomic_int_set (thread_ran, TRUE); + g_task_return_int (task, magic); + } + +@@ -1102,7 +1102,7 @@ test_run_in_thread_sync (void) + g_task_set_task_data (task, &thread_ran, NULL); + g_task_run_in_thread_sync (task, run_in_thread_sync_thread); + +- g_assert (thread_ran == TRUE); ++ g_assert_true (g_atomic_int_get (&thread_ran)); + g_assert (task != NULL); + g_assert (!g_task_had_error (task)); + g_assert_true (g_task_get_completed (task)); +@@ -1487,8 +1487,8 @@ test_return_on_cancel (void) + { + GTask *task; + GCancellable *cancellable; +- volatile ThreadState thread_state; +- volatile gboolean weak_notify_ran = FALSE; ++ ThreadState thread_state; /* (atomic) */ ++ gboolean weak_notify_ran = FALSE; /* (atomic) */ + gboolean callback_ran; + gboolean notification_emitted = FALSE; + +@@ -1498,7 +1498,7 @@ test_return_on_cancel (void) + * early. + */ + callback_ran = FALSE; +- thread_state = THREAD_STARTING; ++ g_atomic_int_set (&thread_state, THREAD_STARTING); + task = g_task_new (NULL, cancellable, return_on_cancel_callback, &callback_ran); + g_signal_connect (task, "notify::completed", + (GCallback) completed_cb, ¬ification_emitted); +@@ -1509,18 +1509,18 @@ test_return_on_cancel (void) + g_task_run_in_thread (task, return_on_cancel_thread); + g_object_unref (task); + +- while (thread_state == THREAD_STARTING) ++ while (g_atomic_int_get (&thread_state) == THREAD_STARTING) + g_cond_wait (&roc_init_cond, &roc_init_mutex); + g_mutex_unlock (&roc_init_mutex); + +- g_assert (thread_state == THREAD_RUNNING); ++ g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING); + g_assert (callback_ran == FALSE); + + g_cancellable_cancel (cancellable); + g_mutex_unlock (&roc_finish_mutex); + g_main_loop_run (loop); + +- g_assert (thread_state == THREAD_COMPLETED); ++ g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_COMPLETED); + g_assert (callback_ran == TRUE); + g_assert_true (notification_emitted); + +@@ -1529,7 +1529,7 @@ test_return_on_cancel (void) + /* If return-on-cancel is TRUE, it does return early */ + callback_ran = FALSE; + notification_emitted = FALSE; +- thread_state = THREAD_STARTING; ++ g_atomic_int_set (&thread_state, THREAD_STARTING); + task = g_task_new (NULL, cancellable, return_on_cancel_callback, &callback_ran); + g_object_weak_ref (G_OBJECT (task), task_weak_notify, (gpointer)&weak_notify_ran); + g_signal_connect (task, "notify::completed", +@@ -1542,27 +1542,27 @@ test_return_on_cancel (void) + g_task_run_in_thread (task, return_on_cancel_thread); + g_object_unref (task); + +- while (thread_state == THREAD_STARTING) ++ while (g_atomic_int_get (&thread_state) == THREAD_STARTING) + g_cond_wait (&roc_init_cond, &roc_init_mutex); + g_mutex_unlock (&roc_init_mutex); + +- g_assert (thread_state == THREAD_RUNNING); ++ g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING); + g_assert (callback_ran == FALSE); + + g_cancellable_cancel (cancellable); + g_main_loop_run (loop); +- g_assert (thread_state == THREAD_RUNNING); ++ g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING); + g_assert (callback_ran == TRUE); + +- g_assert (weak_notify_ran == FALSE); ++ g_assert_false (g_atomic_int_get (&weak_notify_ran)); + +- while (thread_state == THREAD_RUNNING) ++ while (g_atomic_int_get (&thread_state) == THREAD_RUNNING) + g_cond_wait (&roc_finish_cond, &roc_finish_mutex); + g_mutex_unlock (&roc_finish_mutex); + +- g_assert (thread_state == THREAD_CANCELLED); ++ g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_CANCELLED); + g_mutex_lock (&run_in_thread_mutex); +- while (!weak_notify_ran) ++ while (!g_atomic_int_get (&weak_notify_ran)) + g_cond_wait (&run_in_thread_cond, &run_in_thread_mutex); + g_mutex_unlock (&run_in_thread_mutex); + +@@ -1574,7 +1574,7 @@ test_return_on_cancel (void) + */ + callback_ran = FALSE; + notification_emitted = FALSE; +- thread_state = THREAD_STARTING; ++ g_atomic_int_set (&thread_state, THREAD_STARTING); + task = g_task_new (NULL, cancellable, return_on_cancel_callback, &callback_ran); + g_signal_connect (task, "notify::completed", + (GCallback) completed_cb, ¬ification_emitted); +@@ -1591,17 +1591,17 @@ test_return_on_cancel (void) + g_main_loop_run (loop); + g_assert (callback_ran == TRUE); + +- while (thread_state == THREAD_STARTING) ++ while (g_atomic_int_get (&thread_state) == THREAD_STARTING) + g_cond_wait (&roc_init_cond, &roc_init_mutex); + g_mutex_unlock (&roc_init_mutex); + +- g_assert (thread_state == THREAD_RUNNING); ++ g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING); + +- while (thread_state == THREAD_RUNNING) ++ while (g_atomic_int_get (&thread_state) == THREAD_RUNNING) + g_cond_wait (&roc_finish_cond, &roc_finish_mutex); + g_mutex_unlock (&roc_finish_mutex); + +- g_assert (thread_state == THREAD_CANCELLED); ++ g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_CANCELLED); + g_assert_true (notification_emitted); + + g_object_unref (cancellable); +@@ -1621,7 +1621,7 @@ test_return_on_cancel_sync (void) + { + GTask *task; + GCancellable *cancellable; +- volatile ThreadState thread_state; ++ ThreadState thread_state; /* (atomic) */ + GThread *runner_thread; + gssize ret; + GError *error = NULL; +@@ -1630,7 +1630,7 @@ test_return_on_cancel_sync (void) + + /* If return-on-cancel is FALSE, the task does not return early. + */ +- thread_state = THREAD_STARTING; ++ g_atomic_int_set (&thread_state, THREAD_STARTING); + task = g_task_new (NULL, cancellable, run_in_thread_sync_callback, NULL); + + g_task_set_task_data (task, (gpointer)&thread_state, NULL); +@@ -1639,16 +1639,16 @@ test_return_on_cancel_sync (void) + runner_thread = g_thread_new ("return-on-cancel-sync runner thread", + cancel_sync_runner_thread, task); + +- while (thread_state == THREAD_STARTING) ++ while (g_atomic_int_get (&thread_state) == THREAD_STARTING) + g_cond_wait (&roc_init_cond, &roc_init_mutex); + g_mutex_unlock (&roc_init_mutex); + +- g_assert (thread_state == THREAD_RUNNING); ++ g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING); + + g_cancellable_cancel (cancellable); + g_mutex_unlock (&roc_finish_mutex); + g_thread_join (runner_thread); +- g_assert (thread_state == THREAD_COMPLETED); ++ g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_COMPLETED); + + ret = g_task_propagate_int (task, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); +@@ -1660,7 +1660,7 @@ test_return_on_cancel_sync (void) + g_cancellable_reset (cancellable); + + /* If return-on-cancel is TRUE, it does return early */ +- thread_state = THREAD_STARTING; ++ g_atomic_int_set (&thread_state, THREAD_STARTING); + task = g_task_new (NULL, cancellable, run_in_thread_sync_callback, NULL); + g_task_set_return_on_cancel (task, TRUE); + +@@ -1670,15 +1670,15 @@ test_return_on_cancel_sync (void) + runner_thread = g_thread_new ("return-on-cancel-sync runner thread", + cancel_sync_runner_thread, task); + +- while (thread_state == THREAD_STARTING) ++ while (g_atomic_int_get (&thread_state) == THREAD_STARTING) + g_cond_wait (&roc_init_cond, &roc_init_mutex); + g_mutex_unlock (&roc_init_mutex); + +- g_assert (thread_state == THREAD_RUNNING); ++ g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING); + + g_cancellable_cancel (cancellable); + g_thread_join (runner_thread); +- g_assert (thread_state == THREAD_RUNNING); ++ g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING); + + ret = g_task_propagate_int (task, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); +@@ -1687,18 +1687,18 @@ test_return_on_cancel_sync (void) + + g_object_unref (task); + +- while (thread_state == THREAD_RUNNING) ++ while (g_atomic_int_get (&thread_state) == THREAD_RUNNING) + g_cond_wait (&roc_finish_cond, &roc_finish_mutex); + g_mutex_unlock (&roc_finish_mutex); + +- g_assert (thread_state == THREAD_CANCELLED); ++ g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_CANCELLED); + + g_cancellable_reset (cancellable); + + /* If the task is already cancelled before it starts, it returns + * immediately, but the thread func still runs. + */ +- thread_state = THREAD_STARTING; ++ g_atomic_int_set (&thread_state, THREAD_STARTING); + task = g_task_new (NULL, cancellable, run_in_thread_sync_callback, NULL); + g_task_set_return_on_cancel (task, TRUE); + +@@ -1711,7 +1711,7 @@ test_return_on_cancel_sync (void) + cancel_sync_runner_thread, task); + + g_thread_join (runner_thread); +- g_assert (thread_state == THREAD_STARTING); ++ g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_STARTING); + + ret = g_task_propagate_int (task, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); +@@ -1720,17 +1720,17 @@ test_return_on_cancel_sync (void) + + g_object_unref (task); + +- while (thread_state == THREAD_STARTING) ++ while (g_atomic_int_get (&thread_state) == THREAD_STARTING) + g_cond_wait (&roc_init_cond, &roc_init_mutex); + g_mutex_unlock (&roc_init_mutex); + +- g_assert (thread_state == THREAD_RUNNING); ++ g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_RUNNING); + +- while (thread_state == THREAD_RUNNING) ++ while (g_atomic_int_get (&thread_state) == THREAD_RUNNING) + g_cond_wait (&roc_finish_cond, &roc_finish_mutex); + g_mutex_unlock (&roc_finish_mutex); + +- g_assert (thread_state == THREAD_CANCELLED); ++ g_assert_cmpint (g_atomic_int_get (&thread_state), ==, THREAD_CANCELLED); + + g_object_unref (cancellable); + } +@@ -1776,7 +1776,7 @@ return_on_cancel_atomic_thread (GTask *task, + gpointer task_data, + GCancellable *cancellable) + { +- gint *state = task_data; ++ gint *state = task_data; /* (atomic) */ + + g_assert (source_object == g_task_get_source_object (task)); + g_assert (task_data == g_task_get_task_data (task)); +@@ -1784,34 +1784,34 @@ return_on_cancel_atomic_thread (GTask *task, + g_assert_false (g_task_get_completed (task)); + + g_assert (g_thread_self () != main_thread); +- g_assert_cmpint (*state, ==, 0); ++ g_assert_cmpint (g_atomic_int_get (state), ==, 0); + + g_mutex_lock (&roca_mutex_1); +- *state = 1; ++ g_atomic_int_set (state, 1); + g_cond_signal (&roca_cond_1); + g_mutex_unlock (&roca_mutex_1); + + g_mutex_lock (&roca_mutex_2); + if (g_task_set_return_on_cancel (task, FALSE)) +- *state = 2; ++ g_atomic_int_set (state, 2); + else +- *state = 3; ++ g_atomic_int_set (state, 3); + g_cond_signal (&roca_cond_2); + g_mutex_unlock (&roca_mutex_2); + + g_mutex_lock (&roca_mutex_1); + if (g_task_set_return_on_cancel (task, TRUE)) +- *state = 4; ++ g_atomic_int_set (state, 4); + else +- *state = 5; ++ g_atomic_int_set (state, 5); + g_cond_signal (&roca_cond_1); + g_mutex_unlock (&roca_mutex_1); + + g_mutex_lock (&roca_mutex_2); + if (g_task_set_return_on_cancel (task, TRUE)) +- *state = 6; ++ g_atomic_int_set (state, 6); + else +- *state = 7; ++ g_atomic_int_set (state, 7); + g_cond_signal (&roca_cond_2); + g_mutex_unlock (&roca_mutex_2); + +@@ -1823,7 +1823,7 @@ test_return_on_cancel_atomic (void) + { + GTask *task; + GCancellable *cancellable; +- volatile gint state; ++ gint state; /* (atomic) */ + gboolean notification_emitted = FALSE; + gboolean callback_ran; + +@@ -1832,7 +1832,7 @@ test_return_on_cancel_atomic (void) + g_mutex_lock (&roca_mutex_2); + + /* If we don't cancel it, each set_return_on_cancel() call will succeed */ +- state = 0; ++ g_atomic_int_set (&state, 0); + callback_ran = FALSE; + task = g_task_new (NULL, cancellable, return_on_cancel_atomic_callback, &callback_ran); + g_task_set_return_on_cancel (task, TRUE); +@@ -1843,23 +1843,23 @@ test_return_on_cancel_atomic (void) + g_task_run_in_thread (task, return_on_cancel_atomic_thread); + g_object_unref (task); + +- g_assert_cmpint (state, ==, 0); ++ g_assert_cmpint (g_atomic_int_get (&state), ==, 0); + +- while (state == 0) ++ while (g_atomic_int_get (&state) == 0) + g_cond_wait (&roca_cond_1, &roca_mutex_1); +- g_assert (state == 1); ++ g_assert_cmpint (g_atomic_int_get (&state), ==, 1); + +- while (state == 1) ++ while (g_atomic_int_get (&state) == 1) + g_cond_wait (&roca_cond_2, &roca_mutex_2); +- g_assert (state == 2); ++ g_assert_cmpint (g_atomic_int_get (&state), ==, 2); + +- while (state == 2) ++ while (g_atomic_int_get (&state) == 2) + g_cond_wait (&roca_cond_1, &roca_mutex_1); +- g_assert (state == 4); ++ g_assert_cmpint (g_atomic_int_get (&state), ==, 4); + +- while (state == 4) ++ while (g_atomic_int_get (&state) == 4) + g_cond_wait (&roca_cond_2, &roca_mutex_2); +- g_assert (state == 6); ++ g_assert_cmpint (g_atomic_int_get (&state), ==, 6); + + /* callback assumes there'll be a cancelled error */ + g_cancellable_cancel (cancellable); +@@ -1876,7 +1876,7 @@ test_return_on_cancel_atomic (void) + * task won't complete right away, and further + * g_task_set_return_on_cancel() calls will return FALSE. + */ +- state = 0; ++ g_atomic_int_set (&state, 0); + callback_ran = FALSE; + notification_emitted = FALSE; + task = g_task_new (NULL, cancellable, return_on_cancel_atomic_callback, &callback_ran); +@@ -1887,16 +1887,16 @@ test_return_on_cancel_atomic (void) + g_task_set_task_data (task, (gpointer)&state, NULL); + g_task_run_in_thread (task, return_on_cancel_atomic_thread); + +- g_assert_cmpint (state, ==, 0); ++ g_assert_cmpint (g_atomic_int_get (&state), ==, 0); + +- while (state == 0) ++ while (g_atomic_int_get (&state) == 0) + g_cond_wait (&roca_cond_1, &roca_mutex_1); +- g_assert (state == 1); ++ g_assert_cmpint (g_atomic_int_get (&state), ==, 1); + g_assert (g_task_get_return_on_cancel (task)); + +- while (state == 1) ++ while (g_atomic_int_get (&state) == 1) + g_cond_wait (&roca_cond_2, &roca_mutex_2); +- g_assert (state == 2); ++ g_assert_cmpint (g_atomic_int_get (&state), ==, 2); + g_assert (!g_task_get_return_on_cancel (task)); + + g_cancellable_cancel (cancellable); +@@ -1904,18 +1904,18 @@ test_return_on_cancel_atomic (void) + g_main_loop_run (loop); + g_assert (callback_ran == FALSE); + +- while (state == 2) ++ while (g_atomic_int_get (&state) == 2) + g_cond_wait (&roca_cond_1, &roca_mutex_1); +- g_assert (state == 5); ++ g_assert_cmpint (g_atomic_int_get (&state), ==, 5); + g_assert (!g_task_get_return_on_cancel (task)); + + g_main_loop_run (loop); + g_assert (callback_ran == TRUE); + g_assert_true (notification_emitted); + +- while (state == 5) ++ while (g_atomic_int_get (&state) == 5) + g_cond_wait (&roca_cond_2, &roca_mutex_2); +- g_assert (state == 7); ++ g_assert_cmpint (g_atomic_int_get (&state), ==, 7); + + g_object_unref (cancellable); + g_mutex_unlock (&roca_mutex_1); +-- +GitLab + + +From f4607def1695efb50eb49e0586eed0f5557935f2 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Wed, 11 Nov 2020 18:20:37 +0000 +Subject: [PATCH 06/29] tests: Drop unnecessary volatile qualifiers from tests +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +These variables were already (correctly) accessed atomically. The +`volatile` qualifier doesn’t help with that. + +Signed-off-by: Philip Withnall + +Helps: #600 +--- + gio/tests/g-file-info.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/gio/tests/g-file-info.c b/gio/tests/g-file-info.c +index 809b0ec79..1a02b5e0e 100644 +--- a/gio/tests/g-file-info.c ++++ b/gio/tests/g-file-info.c +@@ -221,7 +221,7 @@ test_internal_enhanced_stdio (void) + guint64 size_p0, alsize_p0, size_ps, alsize_ps; + const gchar *id_p0; + const gchar *id_p1; +- volatile guint64 time_p0; ++ guint64 time_p0; + gchar *tmp_dir; + wchar_t *programdata_dir_w; + wchar_t *users_dir_w; +-- +GitLab + + +From 33612404397f87f0cd45da90d3aa9ab60df895ee Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Wed, 11 Nov 2020 18:24:28 +0000 +Subject: [PATCH 07/29] gdbusconnection: Drop unnecessary volatile qualifiers + from variables + +This should introduce no API changes; there are public functions +exported by `GDBusConnection` which still have some (incorrectly) +`volatile` arguments, but dropping those qualifiers would be an API +break. + +Signed-off-by: Philip Withnall + +Helps: #600 +--- + gio/gdbusconnection.c | 22 +++++++++++----------- + 1 file changed, 11 insertions(+), 11 deletions(-) + +diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c +index ed8cf6219..91c365e80 100644 +--- a/gio/gdbusconnection.c ++++ b/gio/gdbusconnection.c +@@ -393,7 +393,7 @@ struct _GDBusConnection + * FLAG_CLOSED is the closed property. It may be read at any time, but + * may only be written while holding @lock. + */ +- volatile gint atomic_flags; ++ gint atomic_flags; /* (atomic) */ + + /* If the connection could not be established during initable_init(), + * this GError will be set. +@@ -1596,7 +1596,7 @@ static gboolean + g_dbus_connection_send_message_unlocked (GDBusConnection *connection, + GDBusMessage *message, + GDBusSendMessageFlags flags, +- volatile guint32 *out_serial, ++ guint32 *out_serial, + GError **error) + { + guchar *blob; +@@ -1741,7 +1741,7 @@ g_dbus_connection_send_message (GDBusConnection *connection, + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + CONNECTION_LOCK (connection); +- ret = g_dbus_connection_send_message_unlocked (connection, message, flags, out_serial, error); ++ ret = g_dbus_connection_send_message_unlocked (connection, message, flags, (guint32 *) out_serial, error); + CONNECTION_UNLOCK (connection); + return ret; + } +@@ -1901,7 +1901,7 @@ g_dbus_connection_send_message_with_reply_unlocked (GDBusConnection *connect + GDBusMessage *message, + GDBusSendMessageFlags flags, + gint timeout_msec, +- volatile guint32 *out_serial, ++ guint32 *out_serial, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +@@ -1909,7 +1909,7 @@ g_dbus_connection_send_message_with_reply_unlocked (GDBusConnection *connect + GTask *task; + SendMessageData *data; + GError *error = NULL; +- volatile guint32 serial; ++ guint32 serial; + + if (out_serial == NULL) + out_serial = &serial; +@@ -2022,7 +2022,7 @@ g_dbus_connection_send_message_with_reply (GDBusConnection *connection, + message, + flags, + timeout_msec, +- out_serial, ++ (guint32 *) out_serial, + cancellable, + callback, + user_data); +@@ -3082,7 +3082,7 @@ g_dbus_connection_get_peer_credentials (GDBusConnection *connection) + + /* ---------------------------------------------------------------------------------------------------- */ + +-static volatile guint _global_filter_id = 1; ++static guint _global_filter_id = 1; /* (atomic) */ + + /** + * g_dbus_connection_add_filter: +@@ -3327,9 +3327,9 @@ args_to_rule (const gchar *sender, + return g_string_free (rule, FALSE); + } + +-static volatile guint _global_subscriber_id = 1; +-static volatile guint _global_registration_id = 1; +-static volatile guint _global_subtree_registration_id = 1; ++static guint _global_subscriber_id = 1; /* (atomic) */ ++static guint _global_registration_id = 1; /* (atomic) */ ++static guint _global_subtree_registration_id = 1; /* (atomic) */ + + /* ---------------------------------------------------------------------------------------------------- */ + +@@ -5992,7 +5992,7 @@ g_dbus_connection_call_sync_internal (GDBusConnection *connection, + message, + send_flags, + timeout_msec, +- NULL, /* volatile guint32 *out_serial */ ++ NULL, /* guint32 *out_serial */ + cancellable, + &local_error); + +-- +GitLab + + +From 7c7623c4a31fb0f2a7176c43acc728093818b58c Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Wed, 11 Nov 2020 18:26:19 +0000 +Subject: [PATCH 08/29] gdbuserror: Drop unnecessary volatile qualifiers from + variables + +This should introduce no API changes. The +`g_dbus_error_register_error_domain()` function still (incorrectly) has +a `volatile` argument, but dropping that qualifier would be an API +break. + +Signed-off-by: Philip Withnall + +Helps: #600 +--- + gio/gdbuserror.c | 28 +++++++++++++++++----------- + 1 file changed, 17 insertions(+), 11 deletions(-) + +diff --git a/gio/gdbuserror.c b/gio/gdbuserror.c +index 682677354..b03a33f27 100644 +--- a/gio/gdbuserror.c ++++ b/gio/gdbuserror.c +@@ -84,12 +84,12 @@ + * GQuark + * foo_bar_error_quark (void) + * { +- * static volatile gsize quark_volatile = 0; ++ * static gsize quark = 0; + * g_dbus_error_register_error_domain ("foo-bar-error-quark", +- * &quark_volatile, ++ * &quark, + * foo_bar_error_entries, + * G_N_ELEMENTS (foo_bar_error_entries)); +- * return (GQuark) quark_volatile; ++ * return (GQuark) quark; + * } + * ]| + * With this setup, a D-Bus peer can transparently pass e.g. %FOO_BAR_ERROR_ANOTHER_ERROR and +@@ -160,12 +160,12 @@ GQuark + g_dbus_error_quark (void) + { + G_STATIC_ASSERT (G_N_ELEMENTS (g_dbus_error_entries) - 1 == G_DBUS_ERROR_PROPERTY_READ_ONLY); +- static volatile gsize quark_volatile = 0; ++ static gsize quark = 0; + g_dbus_error_register_error_domain ("g-dbus-error-quark", +- &quark_volatile, ++ &quark, + g_dbus_error_entries, + G_N_ELEMENTS (g_dbus_error_entries)); +- return (GQuark) quark_volatile; ++ return (GQuark) quark; + } + + /** +@@ -185,25 +185,31 @@ g_dbus_error_register_error_domain (const gchar *error_domain_quark_na + const GDBusErrorEntry *entries, + guint num_entries) + { ++ gsize *quark; ++ + g_return_if_fail (error_domain_quark_name != NULL); + g_return_if_fail (quark_volatile != NULL); + g_return_if_fail (entries != NULL); + g_return_if_fail (num_entries > 0); + +- if (g_once_init_enter (quark_volatile)) ++ /* Drop the volatile qualifier, which should never have been on the argument ++ * in the first place. */ ++ quark = (gsize *) quark_volatile; ++ ++ if (g_once_init_enter (quark)) + { + guint n; +- GQuark quark; ++ GQuark new_quark; + +- quark = g_quark_from_static_string (error_domain_quark_name); ++ new_quark = g_quark_from_static_string (error_domain_quark_name); + + for (n = 0; n < num_entries; n++) + { +- g_warn_if_fail (g_dbus_error_register_error (quark, ++ g_warn_if_fail (g_dbus_error_register_error (new_quark, + entries[n].error_code, + entries[n].dbus_error_name)); + } +- g_once_init_leave (quark_volatile, quark); ++ g_once_init_leave (quark, new_quark); + } + } + +-- +GitLab + + +From 74250cd9c9dfd3ad428e445c095ceac88ba18691 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Wed, 11 Nov 2020 18:28:23 +0000 +Subject: [PATCH 09/29] gio: Drop unnecessary volatile qualifiers from internal + variables +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +These variables were already (correctly) accessed atomically. The +`volatile` qualifier doesn’t help with that. + +Signed-off-by: Philip Withnall + +Helps: #600 +--- + gio/gdbusinterfaceskeleton.c | 2 +- + gio/gdbusintrospection.h | 14 +++++++------- + gio/gdbusnameowning.c | 4 ++-- + gio/gdbusnamewatching.c | 4 ++-- + gio/gdbusprivate.c | 10 +++++----- + gio/gnetworking.c | 2 +- + 6 files changed, 18 insertions(+), 18 deletions(-) + +diff --git a/gio/gdbusinterfaceskeleton.c b/gio/gdbusinterfaceskeleton.c +index 243b4a0a4..76398df36 100644 +--- a/gio/gdbusinterfaceskeleton.c ++++ b/gio/gdbusinterfaceskeleton.c +@@ -458,7 +458,7 @@ dbus_interface_interface_init (GDBusInterfaceIface *iface) + + typedef struct + { +- volatile gint ref_count; ++ gint ref_count; /* (atomic) */ + GDBusInterfaceSkeleton *interface; + GDBusInterfaceMethodCallFunc method_call_func; + GDBusMethodInvocation *invocation; +diff --git a/gio/gdbusintrospection.h b/gio/gdbusintrospection.h +index 14b171055..f2e291787 100644 +--- a/gio/gdbusintrospection.h ++++ b/gio/gdbusintrospection.h +@@ -43,7 +43,7 @@ G_BEGIN_DECLS + struct _GDBusAnnotationInfo + { + /*< public >*/ +- volatile gint ref_count; ++ gint ref_count; /* (atomic) */ + gchar *key; + gchar *value; + GDBusAnnotationInfo **annotations; +@@ -63,7 +63,7 @@ struct _GDBusAnnotationInfo + struct _GDBusArgInfo + { + /*< public >*/ +- volatile gint ref_count; ++ gint ref_count; /* (atomic) */ + gchar *name; + gchar *signature; + GDBusAnnotationInfo **annotations; +@@ -84,7 +84,7 @@ struct _GDBusArgInfo + struct _GDBusMethodInfo + { + /*< public >*/ +- volatile gint ref_count; ++ gint ref_count; /* (atomic) */ + gchar *name; + GDBusArgInfo **in_args; + GDBusArgInfo **out_args; +@@ -105,7 +105,7 @@ struct _GDBusMethodInfo + struct _GDBusSignalInfo + { + /*< public >*/ +- volatile gint ref_count; ++ gint ref_count; /* (atomic) */ + gchar *name; + GDBusArgInfo **args; + GDBusAnnotationInfo **annotations; +@@ -126,7 +126,7 @@ struct _GDBusSignalInfo + struct _GDBusPropertyInfo + { + /*< public >*/ +- volatile gint ref_count; ++ gint ref_count; /* (atomic) */ + gchar *name; + gchar *signature; + GDBusPropertyInfoFlags flags; +@@ -149,7 +149,7 @@ struct _GDBusPropertyInfo + struct _GDBusInterfaceInfo + { + /*< public >*/ +- volatile gint ref_count; ++ gint ref_count; /* (atomic) */ + gchar *name; + GDBusMethodInfo **methods; + GDBusSignalInfo **signals; +@@ -172,7 +172,7 @@ struct _GDBusInterfaceInfo + struct _GDBusNodeInfo + { + /*< public >*/ +- volatile gint ref_count; ++ gint ref_count; /* (atomic) */ + gchar *path; + GDBusInterfaceInfo **interfaces; + GDBusNodeInfo **nodes; +diff --git a/gio/gdbusnameowning.c b/gio/gdbusnameowning.c +index d20e6ffed..1130d6789 100644 +--- a/gio/gdbusnameowning.c ++++ b/gio/gdbusnameowning.c +@@ -55,7 +55,7 @@ typedef enum + + typedef struct + { +- volatile gint ref_count; ++ gint ref_count; /* (atomic) */ + guint id; + GBusNameOwnerFlags flags; + gchar *name; +@@ -73,7 +73,7 @@ typedef struct + guint name_acquired_subscription_id; + guint name_lost_subscription_id; + +- volatile gboolean cancelled; /* must hold lock when reading or modifying */ ++ gboolean cancelled; /* must hold lock when reading or modifying */ + + gboolean needs_release; + } Client; +diff --git a/gio/gdbusnamewatching.c b/gio/gdbusnamewatching.c +index bc2a9119e..8d24700c5 100644 +--- a/gio/gdbusnamewatching.c ++++ b/gio/gdbusnamewatching.c +@@ -56,7 +56,7 @@ typedef enum + + typedef struct + { +- volatile gint ref_count; ++ gint ref_count; /* (atomic) */ + guint id; + gchar *name; + GBusNameWatcherFlags flags; +@@ -78,7 +78,7 @@ typedef struct + } Client; + + /* Must be accessed atomically. */ +-static volatile guint next_global_id = 1; ++static guint next_global_id = 1; /* (atomic) */ + + /* Must be accessed with @lock held. */ + static GHashTable *map_id_to_client = NULL; +diff --git a/gio/gdbusprivate.c b/gio/gdbusprivate.c +index 2551e4791..99b37f3eb 100644 +--- a/gio/gdbusprivate.c ++++ b/gio/gdbusprivate.c +@@ -265,7 +265,7 @@ ensure_required_types (void) + + typedef struct + { +- volatile gint refcount; ++ gint refcount; /* (atomic) */ + GThread *thread; + GMainContext *context; + GMainLoop *loop; +@@ -341,12 +341,12 @@ typedef enum { + + struct GDBusWorker + { +- volatile gint ref_count; ++ gint ref_count; /* (atomic) */ + + SharedThreadData *shared_thread_data; + + /* really a boolean, but GLib 2.28 lacks atomic boolean ops */ +- volatile gint stopped; ++ gint stopped; /* (atomic) */ + + /* TODO: frozen (e.g. G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING) currently + * only affects messages received from the other peer (since GDBusServer is the +@@ -1941,11 +1941,11 @@ _g_dbus_debug_print_unlock (void) + void + _g_dbus_initialize (void) + { +- static volatile gsize initialized = 0; ++ static gsize initialized = 0; + + if (g_once_init_enter (&initialized)) + { +- volatile GQuark g_dbus_error_domain; ++ GQuark g_dbus_error_domain; + const gchar *debug; + + g_dbus_error_domain = G_DBUS_ERROR; +diff --git a/gio/gnetworking.c b/gio/gnetworking.c +index 05507fe70..7bc6d73c4 100644 +--- a/gio/gnetworking.c ++++ b/gio/gnetworking.c +@@ -61,7 +61,7 @@ void + g_networking_init (void) + { + #ifdef G_OS_WIN32 +- static volatile gsize inited = 0; ++ static gsize inited = 0; + + if (g_once_init_enter (&inited)) + { +-- +GitLab + + +From e4e88688a0722237effc56cc21438d0c8e82de88 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Wed, 11 Nov 2020 18:29:26 +0000 +Subject: [PATCH 10/29] kqueue: Fix unlocked access to shared variable +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +And drop the `volatile` qualifier because it doesn’t help. + +Signed-off-by: Philip Withnall + +Helps: #600 +--- + gio/kqueue/kqueue-missing.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/gio/kqueue/kqueue-missing.c b/gio/kqueue/kqueue-missing.c +index 37af82e5b..d1ffdf4bd 100644 +--- a/gio/kqueue/kqueue-missing.c ++++ b/gio/kqueue/kqueue-missing.c +@@ -34,7 +34,7 @@ static gboolean km_debug_enabled = FALSE; + static GSList *missing_subs_list = NULL; + G_LOCK_DEFINE_STATIC (missing_lock); + +-static volatile gboolean scan_missing_running = FALSE; ++static gboolean scan_missing_running = FALSE; /* must be accessed under @missing_lock */ + + + static gboolean +@@ -62,7 +62,6 @@ _km_add_missing (kqueue_sub *sub) + + KM_W ("adding %s to missing list\n", sub->filename); + missing_subs_list = g_slist_prepend (missing_subs_list, sub); +- G_UNLOCK (missing_lock); + + if (!scan_missing_running) + { +@@ -73,6 +72,8 @@ _km_add_missing (kqueue_sub *sub) + g_source_attach (source, GLIB_PRIVATE_CALL (g_get_worker_context) ()); + g_source_unref (source); + } ++ ++ G_UNLOCK (missing_lock); + } + + /** +-- +GitLab + + +From 7cdb68713c1863a27ad82d801756ec74097e8e87 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Wed, 11 Nov 2020 18:30:36 +0000 +Subject: [PATCH 11/29] tests: Drop unnecessary volatile qualifiers from tests +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +These variables were already (correctly) accessed atomically. The +`volatile` qualifier doesn’t help with that. + +Signed-off-by: Philip Withnall + +Helps: #600 +--- + tests/gobject/performance-threaded.c | 2 +- + tests/gobject/performance.c | 4 ++-- + tests/onceinit.c | 16 ++++++++-------- + 3 files changed, 11 insertions(+), 11 deletions(-) + +diff --git a/tests/gobject/performance-threaded.c b/tests/gobject/performance-threaded.c +index 30ea5bd80..c98541d66 100644 +--- a/tests/gobject/performance-threaded.c ++++ b/tests/gobject/performance-threaded.c +@@ -52,7 +52,7 @@ static GType liststore_interfaces[6]; + static gpointer + register_types (void) + { +- static volatile gsize inited = 0; ++ static gsize inited = 0; + if (g_once_init_enter (&inited)) + { + liststore_interfaces[0] = simple_register_class ("GtkBuildable", G_TYPE_INTERFACE, 0); +diff --git a/tests/gobject/performance.c b/tests/gobject/performance.c +index 236ffaed0..163be58b4 100644 +--- a/tests/gobject/performance.c ++++ b/tests/gobject/performance.c +@@ -575,8 +575,8 @@ test_type_check_run (PerformanceTest *test, + gpointer _data) + { + struct TypeCheckTest *data = _data; +- volatile GObject *object = data->object; +- volatile GType type, types[5]; ++ GObject *object = data->object; ++ GType type, types[5]; + int i, j; + + types[0] = test_iface1_get_type (); +diff --git a/tests/onceinit.c b/tests/onceinit.c +index 89ba6a136..9788efcbd 100644 +--- a/tests/onceinit.c ++++ b/tests/onceinit.c +@@ -25,13 +25,13 @@ + + static GMutex tmutex; + static GCond tcond; +-static volatile int thread_call_count = 0; ++static int thread_call_count = 0; /* (atomic) */ + static char dummy_value = 'x'; + + static void + assert_singleton_execution1 (void) + { +- static volatile int seen_execution = 0; ++ static int seen_execution = 0; /* (atomic) */ + int old_seen_execution = g_atomic_int_add (&seen_execution, 1); + if (old_seen_execution != 0) + g_error ("%s: function executed more than once", G_STRFUNC); +@@ -40,7 +40,7 @@ assert_singleton_execution1 (void) + static void + assert_singleton_execution2 (void) + { +- static volatile int seen_execution = 0; ++ static int seen_execution = 0; /* (atomic) */ + int old_seen_execution = g_atomic_int_add (&seen_execution, 1); + if (old_seen_execution != 0) + g_error ("%s: function executed more than once", G_STRFUNC); +@@ -49,7 +49,7 @@ assert_singleton_execution2 (void) + static void + assert_singleton_execution3 (void) + { +- static volatile int seen_execution = 0; ++ static int seen_execution = 0; /* (atomic) */ + int old_seen_execution = g_atomic_int_add (&seen_execution, 1); + if (old_seen_execution != 0) + g_error ("%s: function executed more than once", G_STRFUNC); +@@ -58,7 +58,7 @@ assert_singleton_execution3 (void) + static void + initializer1 (void) + { +- static volatile gsize initialized = 0; ++ static gsize initialized = 0; + if (g_once_init_enter (&initialized)) + { + gsize initval = 42; +@@ -70,7 +70,7 @@ initializer1 (void) + static gpointer + initializer2 (void) + { +- static volatile gsize initialized = 0; ++ static gsize initialized = 0; + if (g_once_init_enter (&initialized)) + { + void *pointer_value = &dummy_value; +@@ -83,7 +83,7 @@ initializer2 (void) + static void + initializer3 (void) + { +- static volatile gsize initialized = 0; ++ static gsize initialized = 0; + if (g_once_init_enter (&initialized)) + { + gsize initval = 42; +@@ -163,7 +163,7 @@ main (int argc, + static void \ + test_initializer_##N (void) \ + { \ +- static volatile gsize initialized = 0; \ ++ static gsize initialized = 0; \ + if (g_once_init_enter (&initialized)) \ + { \ + g_free (g_strdup_printf ("cpuhog%5d", 1)); \ +-- +GitLab + + +From 1a7f0002a052725fb646e136fadd5dad66222d7f Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Wed, 11 Nov 2020 18:31:01 +0000 +Subject: [PATCH 12/29] tests: Fix non-atomic access to some shared variables +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +And drop the `volatile` qualifier from the variables, as that doesn’t +help with thread safety. + +Signed-off-by: Philip Withnall + +Helps: #600 +--- + tests/refcount/objects.c | 8 ++++---- + tests/refcount/properties3.c | 8 ++++---- + 2 files changed, 8 insertions(+), 8 deletions(-) + +diff --git a/tests/refcount/objects.c b/tests/refcount/objects.c +index 963766d00..0c471a42b 100644 +--- a/tests/refcount/objects.c ++++ b/tests/refcount/objects.c +@@ -26,7 +26,7 @@ struct _GTestClass + }; + + static GType my_test_get_type (void); +-static volatile gboolean stopping; ++static gint stopping; /* (atomic) */ + + static void my_test_class_init (GTestClass * klass); + static void my_test_init (GTest * test); +@@ -101,7 +101,7 @@ run_thread (GTest * test) + { + gint i = 1; + +- while (!stopping) { ++ while (!g_atomic_int_get (&stopping)) { + my_test_do_refcount (test); + if ((i++ % 10000) == 0) { + g_print ("."); +@@ -128,7 +128,7 @@ main (int argc, char **argv) + + test_threads = g_array_new (FALSE, FALSE, sizeof (GThread *)); + +- stopping = FALSE; ++ g_atomic_int_set (&stopping, 0); + + for (i = 0; i < n_threads; i++) { + GThread *thread; +@@ -141,7 +141,7 @@ main (int argc, char **argv) + } + g_usleep (5000000); + +- stopping = TRUE; ++ g_atomic_int_set (&stopping, 1); + + g_print ("\nstopping\n"); + +diff --git a/tests/refcount/properties3.c b/tests/refcount/properties3.c +index bc8820661..31f26a46e 100644 +--- a/tests/refcount/properties3.c ++++ b/tests/refcount/properties3.c +@@ -34,7 +34,7 @@ struct _GTestClass + static GType my_test_get_type (void); + G_DEFINE_TYPE (GTest, my_test, G_TYPE_OBJECT) + +-static volatile gboolean stopping; ++static gint stopping; /* (atomic) */ + + static void my_test_get_property (GObject *object, + guint prop_id, +@@ -140,7 +140,7 @@ run_thread (GTest * test) + { + gint i = 1; + +- while (!stopping) { ++ while (!g_atomic_int_get (&stopping)) { + my_test_do_property (test); + if ((i++ % 10000) == 0) + { +@@ -170,7 +170,7 @@ main (int argc, char **argv) + + test_threads = g_array_new (FALSE, FALSE, sizeof (GThread *)); + +- stopping = FALSE; ++ g_atomic_int_set (&stopping, 0); + + for (i = 0; i < n_threads; i++) { + GThread *thread; +@@ -180,7 +180,7 @@ main (int argc, char **argv) + } + g_usleep (30000000); + +- stopping = TRUE; ++ g_atomic_int_set (&stopping, 1); + g_print ("\nstopping\n"); + + /* join all threads */ +-- +GitLab + + +From 3c648457c284b4ba313b8591008d2e18ae4335eb Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Wed, 11 Nov 2020 18:36:37 +0000 +Subject: [PATCH 13/29] gatomic: Drop unnecessary volatile qualifiers from + internal variables +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +It’s not necessary and provides no thread safety guarantees. + +The `volatile` qualifiers on the function arguments have to be kept, as +they are (unfortunately) part of the API. + +Signed-off-by: Philip Withnall + +Helps: #600 +--- + glib/gatomic.c | 34 +++++++++++++++++----------------- + 1 file changed, 17 insertions(+), 17 deletions(-) + +diff --git a/glib/gatomic.c b/glib/gatomic.c +index 8b8c6453d..67f5ba6b4 100644 +--- a/glib/gatomic.c ++++ b/glib/gatomic.c +@@ -316,7 +316,7 @@ guint + gpointer + (g_atomic_pointer_get) (const volatile void *atomic) + { +- return g_atomic_pointer_get ((const volatile gpointer *) atomic); ++ return g_atomic_pointer_get ((gpointer *) atomic); + } + + /** +@@ -335,7 +335,7 @@ void + (g_atomic_pointer_set) (volatile void *atomic, + gpointer newval) + { +- g_atomic_pointer_set ((volatile gpointer *) atomic, newval); ++ g_atomic_pointer_set ((gpointer *) atomic, newval); + } + + /** +@@ -363,7 +363,7 @@ gboolean + gpointer oldval, + gpointer newval) + { +- return g_atomic_pointer_compare_and_exchange ((volatile gpointer *) atomic, ++ return g_atomic_pointer_compare_and_exchange ((gpointer *) atomic, + oldval, newval); + } + +@@ -387,7 +387,7 @@ gssize + (g_atomic_pointer_add) (volatile void *atomic, + gssize val) + { +- return g_atomic_pointer_add ((volatile gpointer *) atomic, val); ++ return g_atomic_pointer_add ((gpointer *) atomic, val); + } + + /** +@@ -411,7 +411,7 @@ gsize + (g_atomic_pointer_and) (volatile void *atomic, + gsize val) + { +- return g_atomic_pointer_and ((volatile gpointer *) atomic, val); ++ return g_atomic_pointer_and ((gpointer *) atomic, val); + } + + /** +@@ -435,7 +435,7 @@ gsize + (g_atomic_pointer_or) (volatile void *atomic, + gsize val) + { +- return g_atomic_pointer_or ((volatile gpointer *) atomic, val); ++ return g_atomic_pointer_or ((gpointer *) atomic, val); + } + + /** +@@ -459,7 +459,7 @@ gsize + (g_atomic_pointer_xor) (volatile void *atomic, + gsize val) + { +- return g_atomic_pointer_xor ((volatile gpointer *) atomic, val); ++ return g_atomic_pointer_xor ((gpointer *) atomic, val); + } + + #elif defined (G_PLATFORM_WIN32) +@@ -591,7 +591,7 @@ guint + gpointer + (g_atomic_pointer_get) (const volatile void *atomic) + { +- const volatile gpointer *ptr = atomic; ++ const gpointer *ptr = atomic; + + MemoryBarrier (); + return *ptr; +@@ -601,7 +601,7 @@ void + (g_atomic_pointer_set) (volatile void *atomic, + gpointer newval) + { +- volatile gpointer *ptr = atomic; ++ gpointer *ptr = atomic; + + *ptr = newval; + MemoryBarrier (); +@@ -797,7 +797,7 @@ guint + gpointer + (g_atomic_pointer_get) (const volatile void *atomic) + { +- const volatile gpointer *ptr = atomic; ++ const gpointer *ptr = atomic; + gpointer value; + + pthread_mutex_lock (&g_atomic_lock); +@@ -811,7 +811,7 @@ void + (g_atomic_pointer_set) (volatile void *atomic, + gpointer newval) + { +- volatile gpointer *ptr = atomic; ++ gpointer *ptr = atomic; + + pthread_mutex_lock (&g_atomic_lock); + *ptr = newval; +@@ -823,7 +823,7 @@ gboolean + gpointer oldval, + gpointer newval) + { +- volatile gpointer *ptr = atomic; ++ gpointer *ptr = atomic; + gboolean success; + + pthread_mutex_lock (&g_atomic_lock); +@@ -840,7 +840,7 @@ gssize + (g_atomic_pointer_add) (volatile void *atomic, + gssize val) + { +- volatile gssize *ptr = atomic; ++ gssize *ptr = atomic; + gssize oldval; + + pthread_mutex_lock (&g_atomic_lock); +@@ -855,7 +855,7 @@ gsize + (g_atomic_pointer_and) (volatile void *atomic, + gsize val) + { +- volatile gsize *ptr = atomic; ++ gsize *ptr = atomic; + gsize oldval; + + pthread_mutex_lock (&g_atomic_lock); +@@ -870,7 +870,7 @@ gsize + (g_atomic_pointer_or) (volatile void *atomic, + gsize val) + { +- volatile gsize *ptr = atomic; ++ gsize *ptr = atomic; + gsize oldval; + + pthread_mutex_lock (&g_atomic_lock); +@@ -885,7 +885,7 @@ gsize + (g_atomic_pointer_xor) (volatile void *atomic, + gsize val) + { +- volatile gsize *ptr = atomic; ++ gsize *ptr = atomic; + gsize oldval; + + pthread_mutex_lock (&g_atomic_lock); +@@ -915,5 +915,5 @@ gint + g_atomic_int_exchange_and_add (volatile gint *atomic, + gint val) + { +- return (g_atomic_int_add) (atomic, val); ++ return (g_atomic_int_add) ((gint *) atomic, val); + } +-- +GitLab + + +From 9474655eb21d64519b293e780bb686976cbdb790 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Wed, 11 Nov 2020 18:38:36 +0000 +Subject: [PATCH 14/29] gatomic: Drop unnecessary volatile qualifiers from + macro variables +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +It’s not necessary and provides no thread safety guarantees. + +The `volatile` qualifiers on the function arguments have to be kept, as +they are (unfortunately) part of the API. + +Signed-off-by: Philip Withnall + +Helps: #600 +--- + glib/gatomic.h | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/glib/gatomic.h b/glib/gatomic.h +index bb1435c70..e6eccfada 100644 +--- a/glib/gatomic.h ++++ b/glib/gatomic.h +@@ -211,7 +211,7 @@ G_END_DECLS + })) + #define g_atomic_pointer_and(atomic, val) \ + (G_GNUC_EXTENSION ({ \ +- volatile gsize *gapa_atomic = (volatile gsize *) (atomic); \ ++ gsize *gapa_atomic = (gsize *) (atomic); \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gsize)); \ + (void) (0 ? (gpointer) *(atomic) : NULL); \ +@@ -220,7 +220,7 @@ G_END_DECLS + })) + #define g_atomic_pointer_or(atomic, val) \ + (G_GNUC_EXTENSION ({ \ +- volatile gsize *gapo_atomic = (volatile gsize *) (atomic); \ ++ gsize *gapo_atomic = (gsize *) (atomic); \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gsize)); \ + (void) (0 ? (gpointer) *(atomic) : NULL); \ +@@ -229,7 +229,7 @@ G_END_DECLS + })) + #define g_atomic_pointer_xor(atomic, val) \ + (G_GNUC_EXTENSION ({ \ +- volatile gsize *gapx_atomic = (volatile gsize *) (atomic); \ ++ gsize *gapx_atomic = (gsize *) (atomic); \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gsize)); \ + (void) (0 ? (gpointer) *(atomic) : NULL); \ +-- +GitLab + + +From 1314ff93fc4d3379483c33da6a7deff27f71ed95 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Wed, 11 Nov 2020 18:40:56 +0000 +Subject: [PATCH 15/29] glib: Drop unnecessary volatile qualifiers from + internal variables +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +These variables were already (correctly) accessed atomically. The +`volatile` qualifier doesn’t help with that. + +Signed-off-by: Philip Withnall + +Helps: #600 +--- + glib/gdatetime.c | 2 +- + glib/gkeyfile.c | 2 +- + glib/gmain.c | 8 ++++---- + glib/gmarkup.c | 2 +- + glib/gregex.c | 6 +++--- + glib/gthread.c | 6 +++--- + 6 files changed, 13 insertions(+), 13 deletions(-) + +diff --git a/glib/gdatetime.c b/glib/gdatetime.c +index 1755257be..453077f6d 100644 +--- a/glib/gdatetime.c ++++ b/glib/gdatetime.c +@@ -126,7 +126,7 @@ struct _GDateTime + /* 1 is 0001-01-01 in Proleptic Gregorian */ + gint32 days; + +- volatile gint ref_count; ++ gint ref_count; /* (atomic) */ + }; + + /* Time conversion {{{1 */ +diff --git a/glib/gkeyfile.c b/glib/gkeyfile.c +index 9d0215331..bbe638b74 100644 +--- a/glib/gkeyfile.c ++++ b/glib/gkeyfile.c +@@ -512,7 +512,7 @@ struct _GKeyFile + + gchar **locales; + +- volatile gint ref_count; ++ gint ref_count; /* (atomic) */ + }; + + typedef struct _GKeyFileKeyValuePair GKeyFileKeyValuePair; +diff --git a/glib/gmain.c b/glib/gmain.c +index 772b8ecfc..9c5f0ef1e 100644 +--- a/glib/gmain.c ++++ b/glib/gmain.c +@@ -272,7 +272,7 @@ struct _GMainContext + guint owner_count; + GSList *waiters; + +- volatile gint ref_count; ++ gint ref_count; /* (atomic) */ + + GHashTable *sources; /* guint -> GSource */ + +@@ -303,7 +303,7 @@ struct _GMainContext + + struct _GSourceCallback + { +- volatile gint ref_count; ++ gint ref_count; /* (atomic) */ + GSourceFunc func; + gpointer data; + GDestroyNotify notify; +@@ -313,7 +313,7 @@ struct _GMainLoop + { + GMainContext *context; + gboolean is_running; /* (atomic) */ +- volatile gint ref_count; ++ gint ref_count; /* (atomic) */ + }; + + struct _GTimeoutSource +@@ -4749,7 +4749,7 @@ g_main_context_get_poll_func (GMainContext *context) + * + * |[ + * #define NUM_TASKS 10 +- * static volatile gint tasks_remaining = NUM_TASKS; ++ * static gint tasks_remaining = NUM_TASKS; // (atomic) + * ... + * + * while (g_atomic_int_get (&tasks_remaining) != 0) +diff --git a/glib/gmarkup.c b/glib/gmarkup.c +index ba4dfd2e4..b8327fb6d 100644 +--- a/glib/gmarkup.c ++++ b/glib/gmarkup.c +@@ -119,7 +119,7 @@ struct _GMarkupParseContext + { + const GMarkupParser *parser; + +- volatile gint ref_count; ++ gint ref_count; /* (atomic) */ + + GMarkupParseFlags flags; + +diff --git a/glib/gregex.c b/glib/gregex.c +index 52416bbb9..5e6ddfb46 100644 +--- a/glib/gregex.c ++++ b/glib/gregex.c +@@ -203,7 +203,7 @@ G_STATIC_ASSERT (G_REGEX_RAW == PCRE_UTF8); + + struct _GMatchInfo + { +- volatile gint ref_count; /* the ref count */ ++ gint ref_count; /* the ref count (atomic) */ + GRegex *regex; /* the regex */ + GRegexMatchFlags match_opts; /* options used at match time on the regex */ + gint matches; /* number of matching sub patterns */ +@@ -218,7 +218,7 @@ struct _GMatchInfo + + struct _GRegex + { +- volatile gint ref_count; /* the ref count for the immutable part */ ++ gint ref_count; /* the ref count for the immutable part (atomic) */ + gchar *pattern; /* the pattern */ + pcre *pcre_re; /* compiled form of the pattern */ + GRegexCompileFlags compile_opts; /* options used at compile time on the pattern */ +@@ -1300,7 +1300,7 @@ g_regex_new (const gchar *pattern, + pcre *re; + const gchar *errmsg; + gboolean optimize = FALSE; +- static volatile gsize initialised = 0; ++ static gsize initialised = 0; + + g_return_val_if_fail (pattern != NULL, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); +diff --git a/glib/gthread.c b/glib/gthread.c +index 53f3a0848..612a9739f 100644 +--- a/glib/gthread.c ++++ b/glib/gthread.c +@@ -513,7 +513,7 @@ static GMutex g_once_mutex; + static GCond g_once_cond; + static GSList *g_once_init_list = NULL; + +-static volatile guint g_thread_n_created_counter = 0; ++static guint g_thread_n_created_counter = 0; /* (atomic) */ + + static void g_thread_cleanup (gpointer data); + static GPrivate g_thread_specific_private = G_PRIVATE_INIT (g_thread_cleanup); +@@ -694,7 +694,7 @@ g_once_impl (GOnce *once, + gboolean + (g_once_init_enter) (volatile void *location) + { +- volatile gsize *value_location = location; ++ gsize *value_location = (gsize *) location; + gboolean need_init = FALSE; + g_mutex_lock (&g_once_mutex); + if (g_atomic_pointer_get (value_location) == 0) +@@ -731,7 +731,7 @@ void + (g_once_init_leave) (volatile void *location, + gsize result) + { +- volatile gsize *value_location = location; ++ gsize *value_location = (gsize *) location; + + g_return_if_fail (g_atomic_pointer_get (value_location) == 0); + g_return_if_fail (result != 0); +-- +GitLab + + +From 08d04d0428cc26935a2d42083f1710432465c98a Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Wed, 11 Nov 2020 18:42:43 +0000 +Subject: [PATCH 16/29] gobject: Drop unnecessary volatile qualifiers from + internal variables +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +These variables were already (correctly) accessed atomically. The +`volatile` qualifier doesn’t help with that. + +Signed-off-by: Philip Withnall + +Helps: #600 +--- + gobject/gclosure.c | 2 +- + gobject/gclosure.h | 20 ++++++++++---------- + gobject/gobject.c | 4 ++-- + gobject/gtype.c | 10 +++++----- + 4 files changed, 18 insertions(+), 18 deletions(-) + +diff --git a/gobject/gclosure.c b/gobject/gclosure.c +index 1d1f2f48a..6d41e6d8a 100644 +--- a/gobject/gclosure.c ++++ b/gobject/gclosure.c +@@ -98,7 +98,7 @@ + + typedef union { + GClosure closure; +- volatile gint vint; ++ gint vint; + } ClosureInt; + + #define CHANGE_FIELD(_closure, _field, _OP, _value, _must_set, _SET_OLD, _SET_NEW) \ +diff --git a/gobject/gclosure.h b/gobject/gclosure.h +index a0f91f538..884e403a8 100644 +--- a/gobject/gclosure.h ++++ b/gobject/gclosure.h +@@ -175,20 +175,20 @@ struct _GClosureNotifyData + struct _GClosure + { + /*< private >*/ +- volatile guint ref_count : 15; ++ guint ref_count : 15; /* (atomic) */ + /* meta_marshal is not used anymore but must be zero for historical reasons + as it was exposed in the G_CLOSURE_N_NOTIFIERS macro */ +- volatile guint meta_marshal_nouse : 1; +- volatile guint n_guards : 1; +- volatile guint n_fnotifiers : 2; /* finalization notifiers */ +- volatile guint n_inotifiers : 8; /* invalidation notifiers */ +- volatile guint in_inotify : 1; +- volatile guint floating : 1; ++ guint meta_marshal_nouse : 1; /* (atomic) */ ++ guint n_guards : 1; /* (atomic) */ ++ guint n_fnotifiers : 2; /* finalization notifiers (atomic) */ ++ guint n_inotifiers : 8; /* invalidation notifiers (atomic) */ ++ guint in_inotify : 1; /* (atomic) */ ++ guint floating : 1; /* (atomic) */ + /*< protected >*/ +- volatile guint derivative_flag : 1; ++ guint derivative_flag : 1; /* (atomic) */ + /*< public >*/ +- volatile guint in_marshal : 1; +- volatile guint is_invalid : 1; ++ guint in_marshal : 1; /* (atomic) */ ++ guint is_invalid : 1; /* (atomic) */ + + /*< private >*/ void (*marshal) (GClosure *closure, + GValue /*out*/ *return_value, +diff --git a/gobject/gobject.c b/gobject/gobject.c +index 6e9c44a1e..a3a32be9f 100644 +--- a/gobject/gobject.c ++++ b/gobject/gobject.c +@@ -174,9 +174,9 @@ typedef struct + GTypeInstance g_type_instance; + + /*< private >*/ +- volatile guint ref_count; ++ guint ref_count; /* (atomic) */ + #ifdef HAVE_OPTIONAL_FLAGS +- volatile guint optional_flags; ++ guint optional_flags; /* (atomic) */ + #endif + GData *qdata; + } GObjectReal; +diff --git a/gobject/gtype.c b/gobject/gtype.c +index 51dad7690..be5989a3e 100644 +--- a/gobject/gtype.c ++++ b/gobject/gtype.c +@@ -221,9 +221,9 @@ typedef enum + /* --- structures --- */ + struct _TypeNode + { +- guint volatile ref_count; ++ guint ref_count; /* (atomic) */ + #ifdef G_ENABLE_DEBUG +- guint volatile instance_count; ++ guint instance_count; /* (atomic) */ + #endif + GTypePlugin *plugin; + guint n_children; /* writable with lock */ +@@ -233,7 +233,7 @@ struct _TypeNode + guint is_instantiatable : 1; + guint mutatable_check_cache : 1; /* combines some common path checks */ + GType *children; /* writable with lock */ +- TypeData * volatile data; ++ TypeData *data; + GQuark qname; + GData *global_gdata; + union { +@@ -569,8 +569,8 @@ type_node_new_W (TypeNode *pnode, + } + + static inline IFaceEntry* +-lookup_iface_entry_I (volatile IFaceEntries *entries, +- TypeNode *iface_node) ++lookup_iface_entry_I (IFaceEntries *entries, ++ TypeNode *iface_node) + { + guint8 *offsets; + guint offset_index; +-- +GitLab + + +From eee7e3c6688f2f1ee9beed5d6d209973c1df387e Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Wed, 11 Nov 2020 19:14:25 +0000 +Subject: [PATCH 17/29] gmessages: Drop unnecessary volatile qualifiers from + macro variables +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +It’s not necessary and provides no thread safety guarantees. + +Signed-off-by: Philip Withnall + +Helps: #600 +--- + glib/gmessages.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/glib/gmessages.h b/glib/gmessages.h +index 6a28443b4..2e3650baf 100644 +--- a/glib/gmessages.h ++++ b/glib/gmessages.h +@@ -478,7 +478,7 @@ g_debug (const gchar *format, + #if defined(G_HAVE_ISO_VARARGS) && !G_ANALYZER_ANALYZING + #define g_warning_once(...) \ + G_STMT_START { \ +- static volatile int G_PASTE (_GWarningOnceBoolean, __LINE__) = 0; \ ++ static int G_PASTE (_GWarningOnceBoolean, __LINE__) = 0; /* (atomic) */ \ + if (g_atomic_int_compare_and_exchange (&G_PASTE (_GWarningOnceBoolean, __LINE__), \ + 0, 1)) \ + g_warning (__VA_ARGS__); \ +@@ -487,7 +487,7 @@ g_debug (const gchar *format, + #elif defined(G_HAVE_GNUC_VARARGS) && !G_ANALYZER_ANALYZING + #define g_warning_once(format...) \ + G_STMT_START { \ +- static volatile int G_PASTE (_GWarningOnceBoolean, __LINE__) = 0; \ ++ static int G_PASTE (_GWarningOnceBoolean, __LINE__) = 0; /* (atomic) */ \ + if (g_atomic_int_compare_and_exchange (&G_PASTE (_GWarningOnceBoolean, __LINE__), \ + 0, 1)) \ + g_warning (format); \ +-- +GitLab + + +From 8a87069ff42a0631dce153701cb2ec5e343a958c Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Wed, 11 Nov 2020 19:16:30 +0000 +Subject: [PATCH 18/29] gtypes: Drop volatile qualifier from gatomicrefcount + +This is technically an API break, but since the type is meant to be +opaque (third party code is not meant to treat it like an integer) it +should not cause problems. + +Signed-off-by: Philip Withnall + +Helps: #600 +--- + glib/gtypes.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/glib/gtypes.h b/glib/gtypes.h +index 23c5a1295..2c4825582 100644 +--- a/glib/gtypes.h ++++ b/glib/gtypes.h +@@ -550,8 +550,8 @@ struct _GTimeVal + glong tv_usec; + } GLIB_DEPRECATED_TYPE_IN_2_62_FOR(GDateTime); + +-typedef gint grefcount; +-typedef volatile gint gatomicrefcount; ++typedef gint grefcount; ++typedef gint gatomicrefcount; /* should be accessed only using atomics */ + + G_END_DECLS + +-- +GitLab + + +From 46bae4f18dfec8fedda82648091752d270b2dff8 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Wed, 11 Nov 2020 19:19:20 +0000 +Subject: [PATCH 19/29] gatomicarray: Drop volatile qualifier from GAtomicArray + API + +This is an API break, but it should not affect third party code since +that code should not be interacting with the `data` member in a way that +invokes its `volatile` qualifier (such as copying to an intermediate +variable). + +Signed-off-by: Philip Withnall + +Helps: #600 +--- + gobject/gatomicarray.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/gobject/gatomicarray.h b/gobject/gatomicarray.h +index 9550fa396..89043c5e4 100644 +--- a/gobject/gatomicarray.h ++++ b/gobject/gatomicarray.h +@@ -29,7 +29,7 @@ G_BEGIN_DECLS + + typedef struct _GAtomicArray GAtomicArray; + struct _GAtomicArray { +- volatile gpointer data; /* elements - atomic */ ++ gpointer data; /* elements - atomic */ + }; + + void _g_atomic_array_init (GAtomicArray *array); +@@ -42,7 +42,7 @@ void _g_atomic_array_update (GAtomicArray *array, + #define G_ATOMIC_ARRAY_GET_LOCKED(_array, _type) ((_type *)((_array)->data)) + + #define G_ATOMIC_ARRAY_DO_TRANSACTION(_array, _type, _C_) G_STMT_START { \ +- volatile gpointer *_datap = &(_array)->data; \ ++ gpointer *_datap = &(_array)->data; \ + _type *transaction_data, *__check; \ + \ + __check = g_atomic_pointer_get (_datap); \ +-- +GitLab + + +From 334f6953364680ddc6c0d3da13fda1d92bf5379d Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Wed, 11 Nov 2020 19:21:07 +0000 +Subject: [PATCH 20/29] gobject: Drop volatile qualifier from GObject.ref_count + +This is an API break, but no third party code should be touching +`GObject.ref_count`, let alone in a way which would be changed by the +removal of the `volatile` qualifier. + +Signed-off-by: Philip Withnall + +Helps: #600 +--- + gobject/gobject.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/gobject/gobject.h b/gobject/gobject.h +index 7f55e1976..a84c183f8 100644 +--- a/gobject/gobject.h ++++ b/gobject/gobject.h +@@ -247,7 +247,7 @@ struct _GObject + GTypeInstance g_type_instance; + + /*< private >*/ +- volatile guint ref_count; ++ guint ref_count; /* (atomic) */ + GData *qdata; + }; + /** +-- +GitLab + + +From 8a112c3c6e5fe6838ee29eec7caa62ba32d9bc40 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Wed, 11 Nov 2020 19:22:49 +0000 +Subject: [PATCH 21/29] tests: Drop unnecessary volatile qualifiers from tests +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +These variables were already (correctly) accessed atomically. The +`volatile` qualifier doesn’t help with that. + +Signed-off-by: Philip Withnall + +Helps: #600 +--- + gobject/tests/qdata.c | 2 +- + gobject/tests/threadtests.c | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/gobject/tests/qdata.c b/gobject/tests/qdata.c +index 528bdc68e..7d46efb15 100644 +--- a/gobject/tests/qdata.c ++++ b/gobject/tests/qdata.c +@@ -17,7 +17,7 @@ gboolean fail; + #define ROUNDS 10000 + + GObject *object; +-volatile gint bucket[THREADS]; ++gint bucket[THREADS]; /* accessed from multiple threads, but should never be contested due to the sequence of thread operations */ + + static gpointer + thread_func (gpointer data) +diff --git a/gobject/tests/threadtests.c b/gobject/tests/threadtests.c +index e341a9d67..b6f9e17fa 100644 +--- a/gobject/tests/threadtests.c ++++ b/gobject/tests/threadtests.c +@@ -27,8 +27,8 @@ + #include + #include + +-static volatile int mtsafe_call_counter = 0; /* multi thread safe call counter */ +-static int unsafe_call_counter = 0; /* single-threaded call counter */ ++static int mtsafe_call_counter = 0; /* multi thread safe call counter, must be accessed atomically */ ++static int unsafe_call_counter = 0; /* single-threaded call counter */ + static GCond sync_cond; + static GMutex sync_mutex; + +-- +GitLab + + +From daf90bfa99fc02a253d538c65fbaa12f2e6c1c45 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Wed, 11 Nov 2020 19:23:18 +0000 +Subject: [PATCH 22/29] build: Drop unnecessary volatile qualifiers from + configure tests + +Signed-off-by: Philip Withnall + +Helps: #600 +--- + meson.build | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/meson.build b/meson.build +index e0b308a25..ad7f887fb 100644 +--- a/meson.build ++++ b/meson.build +@@ -1773,7 +1773,7 @@ endforeach + # that then to silently fall back on emulated atomic ops just because + # the user had the wrong build environment. + atomictest = '''int main() { +- volatile int atomic = 2; ++ int atomic = 2; + __sync_bool_compare_and_swap (&atomic, 2, 3); + return 0; + } +@@ -1883,6 +1883,7 @@ endif + + # FIXME: we should make it print the result and always return 0, so that + # the output in meson shows up as green ++# volatile is needed here to avoid optimisations in the test + stack_grows_check_prog = ''' + volatile int *a = 0, *b = 0; + void f (int i) { +-- +GitLab + + +From 0604f5858259c32744e6fc912ed4feb308651a3a Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Mon, 16 Nov 2020 14:47:23 +0000 +Subject: [PATCH 23/29] gdbusprivate: Avoid a warning about a statement with no + effect + +Signed-off-by: Philip Withnall +--- + gio/gdbusprivate.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/gio/gdbusprivate.c b/gio/gdbusprivate.c +index 99b37f3eb..4e42c1a4d 100644 +--- a/gio/gdbusprivate.c ++++ b/gio/gdbusprivate.c +@@ -1945,11 +1945,10 @@ _g_dbus_initialize (void) + + if (g_once_init_enter (&initialized)) + { +- GQuark g_dbus_error_domain; + const gchar *debug; + +- g_dbus_error_domain = G_DBUS_ERROR; +- (g_dbus_error_domain); /* To avoid -Wunused-but-set-variable */ ++ /* Ensure the domain is registered. */ ++ g_dbus_error_quark (); + + debug = g_getenv ("G_DBUS_DEBUG"); + if (debug != NULL) +-- +GitLab + + +From 2d03f99ae4de394cac0690717d96c2d884ccdae2 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Mon, 16 Nov 2020 14:47:47 +0000 +Subject: [PATCH 24/29] tests: Add comment to volatile atomic tests +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +`volatile` should not be used to indicate atomic variables, and we +shouldn’t encourage its use. Keep the tests, since they check that we +don’t emit warnings when built against incorrect old code which uses +`volatile`. But add a comment to stop copy/paste use of `volatile` +in the future. + +Signed-off-by: Philip Withnall + +Helps: #600 +--- + glib/tests/atomic.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/glib/tests/atomic.c b/glib/tests/atomic.c +index 7d2459f3a..14e6e454e 100644 +--- a/glib/tests/atomic.c ++++ b/glib/tests/atomic.c +@@ -94,6 +94,9 @@ test_types (void) + res = g_atomic_pointer_compare_and_exchange (&vp_str, NULL, str); + g_assert_true (res); + ++ /* Note that atomic variables should almost certainly not be marked as ++ * `volatile` — see http://isvolatileusefulwiththreads.in/c/. This test exists ++ * to make sure that we don’t warn when built against older third party code. */ + g_atomic_pointer_set (&vp_str_vol, NULL); + res = g_atomic_pointer_compare_and_exchange (&vp_str_vol, NULL, str); + g_assert_true (res); +@@ -210,6 +213,9 @@ G_GNUC_END_IGNORE_DEPRECATIONS + res = g_atomic_pointer_compare_and_exchange (&vp_str, NULL, (char *) str); + g_assert_true (res); + ++ /* Note that atomic variables should almost certainly not be marked as ++ * `volatile` — see http://isvolatileusefulwiththreads.in/c/. This test exists ++ * to make sure that we don’t warn when built against older third party code. */ + g_atomic_pointer_set (&vp_str_vol, NULL); + res = g_atomic_pointer_compare_and_exchange (&vp_str_vol, NULL, (char *) str); + g_assert_true (res); +-- +GitLab + + +From 6bd0a4b29753570a2c20b61b5ad2c0068567b7b6 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Mon, 16 Nov 2020 16:44:29 +0000 +Subject: [PATCH 25/29] gthread: Use g_atomic() primitives correctly in + destructor list +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +In the Windows destructor list, consistently access +`g_private_destructors` using atomic primitives. + +`g_atomic_pointer_compare_and_exchange()` should be equivalent to +`InterlockedCompareExchangePointer()`, but is a bit more understandable +in a general GLib context, and pairs with `g_atomic_pointer_get()`. (I +can’t find a Windows API equivalent for that.) + +Signed-off-by: Philip Withnall + +Helps: #600 +--- + glib/gthread-win32.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/glib/gthread-win32.c b/glib/gthread-win32.c +index 0c37dc6c1..20aca6fa1 100644 +--- a/glib/gthread-win32.c ++++ b/glib/gthread-win32.c +@@ -301,7 +301,7 @@ struct _GPrivateDestructor + GPrivateDestructor *next; + }; + +-static GPrivateDestructor * volatile g_private_destructors; ++static GPrivateDestructor *g_private_destructors; /* (atomic) prepend-only */ + static CRITICAL_SECTION g_private_lock; + + static DWORD +@@ -329,7 +329,7 @@ g_private_get_impl (GPrivate *key) + g_thread_abort (errno, "malloc"); + destructor->index = impl; + destructor->notify = key->notify; +- destructor->next = g_private_destructors; ++ destructor->next = g_atomic_pointer_get (&g_private_destructors); + + /* We need to do an atomic store due to the unlocked + * access to the destructor list from the thread exit +@@ -337,13 +337,14 @@ g_private_get_impl (GPrivate *key) + * + * It can double as a sanity check... + */ +- if (InterlockedCompareExchangePointer (&g_private_destructors, destructor, +- destructor->next) != destructor->next) ++ if (!g_atomic_pointer_compare_and_exchange (&g_private_destructors, ++ destructor->next, ++ destructor)) + g_thread_abort (0, "g_private_get_impl(1)"); + } + + /* Ditto, due to the unlocked access on the fast path */ +- if (InterlockedCompareExchangePointer (&key->p, impl, NULL) != NULL) ++ if (!g_atomic_pointer_compare_and_exchange (&key->p, NULL, impl)) + g_thread_abort (0, "g_private_get_impl(2)"); + } + LeaveCriticalSection (&g_private_lock); +@@ -635,7 +636,7 @@ g_thread_win32_thread_detach (void) + */ + dtors_called = FALSE; + +- for (dtor = g_private_destructors; dtor; dtor = dtor->next) ++ for (dtor = g_atomic_pointer_get (&g_private_destructors); dtor; dtor = dtor->next) + { + gpointer value; + +-- +GitLab + + +From 041dd8b70bd14b041d6a495492eb7a5fc7568bb7 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Mon, 16 Nov 2020 16:47:54 +0000 +Subject: [PATCH 26/29] gtype: Fix some typos in comments + +Signed-off-by: Philip Withnall +--- + gobject/gtype.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/gobject/gtype.c b/gobject/gtype.c +index be5989a3e..ae1af8a05 100644 +--- a/gobject/gtype.c ++++ b/gobject/gtype.c +@@ -2290,7 +2290,7 @@ type_class_init_Wm (TypeNode *node, + * inherited interfaces are already init_state == INITIALIZED, because + * they either got setup in the above base_init loop, or during + * class_init from within type_add_interface_Wm() for this or +- * an anchestor type. ++ * an ancestor type. + */ + i = 0; + while ((entries = CLASSED_NODE_IFACES_ENTRIES_LOCKED (node)) != NULL) +@@ -3462,7 +3462,7 @@ g_type_depth (GType type) + * be used to determine the types and order in which the leaf type is + * descended from the root type. + * +- * Returns: immediate child of @root_type and anchestor of @leaf_type ++ * Returns: immediate child of @root_type and ancestor of @leaf_type + */ + GType + g_type_next_base (GType type, +@@ -3549,8 +3549,8 @@ type_node_conforms_to_U (TypeNode *node, + + /** + * g_type_is_a: +- * @type: type to check anchestry for +- * @is_a_type: possible anchestor of @type or interface that @type ++ * @type: type to check ancestry for ++ * @is_a_type: possible ancestor of @type or interface that @type + * could conform to + * + * If @is_a_type is a derivable type, check whether @type is a +-- +GitLab + + +From 47da8ec5d9a284e07f77c7d59fc8eacf3ebf188a Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Mon, 16 Nov 2020 16:57:22 +0000 +Subject: [PATCH 27/29] gtype: Add some missing atomic accesses to init_state +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Half of the references to `init_state` in `gtype.c` already correctly +accessed it atomically, but a couple didn’t. Drop the `volatile` +qualifier from its declaration, as that’s not necessary for atomic +access. + +Note that this is the `init_state` in `TypeData`, *not* the `init_state` +in `IFaceEntry`. + +Signed-off-by: Philip Withnall + +Helps: #600 +--- + gobject/gtype.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/gobject/gtype.c b/gobject/gtype.c +index ae1af8a05..909faf138 100644 +--- a/gobject/gtype.c ++++ b/gobject/gtype.c +@@ -322,7 +322,7 @@ struct _ClassData + CommonData common; + guint16 class_size; + guint16 class_private_size; +- int volatile init_state; /* atomic - g_type_class_ref reads it unlocked */ ++ int init_state; /* (atomic) - g_type_class_ref reads it unlocked */ + GBaseInitFunc class_init_base; + GBaseFinalizeFunc class_finalize_base; + GClassInitFunc class_init; +@@ -336,7 +336,7 @@ struct _InstanceData + CommonData common; + guint16 class_size; + guint16 class_private_size; +- int volatile init_state; /* atomic - g_type_class_ref reads it unlocked */ ++ int init_state; /* (atomic) - g_type_class_ref reads it unlocked */ + GBaseInitFunc class_init_base; + GBaseFinalizeFunc class_finalize_base; + GClassInitFunc class_init; +@@ -1415,7 +1415,7 @@ type_node_add_iface_entry_W (TypeNode *node, + + if (parent_entry) + { +- if (node->data && node->data->class.init_state >= BASE_IFACE_INIT) ++ if (node->data && g_atomic_int_get (&node->data->class.init_state) >= BASE_IFACE_INIT) + { + entries->entry[i].init_state = INITIALIZED; + entries->entry[i].vtable = parent_entry->vtable; +@@ -1481,7 +1481,7 @@ type_add_interface_Wm (TypeNode *node, + */ + if (node->data) + { +- InitState class_state = node->data->class.init_state; ++ InitState class_state = g_atomic_int_get (&node->data->class.init_state); + + if (class_state >= BASE_IFACE_INIT) + type_iface_vtable_base_init_Wm (iface, node); +@@ -2175,7 +2175,7 @@ type_class_init_Wm (TypeNode *node, + g_assert (node->is_classed && node->data && + node->data->class.class_size && + !node->data->class.class && +- node->data->class.init_state == UNINITIALIZED); ++ g_atomic_int_get (&node->data->class.init_state) == UNINITIALIZED); + if (node->data->class.class_private_size) + class = g_malloc0 (ALIGN_STRUCT (node->data->class.class_size) + node->data->class.class_private_size); + else +-- +GitLab + + +From 7d417f8406b8fa32a25659120738d22be6a1b482 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Mon, 16 Nov 2020 17:17:21 +0000 +Subject: [PATCH 28/29] gresource: Fix a pointer mismatch with an atomic load + +This squashes a warning when compiling with Clang. + +Signed-off-by: Philip Withnall +--- + gio/gresource.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/gio/gresource.c b/gio/gresource.c +index 79a49d33d..b495d12ac 100644 +--- a/gio/gresource.c ++++ b/gio/gresource.c +@@ -1398,7 +1398,7 @@ register_lazy_static_resources (void) + void + g_static_resource_init (GStaticResource *static_resource) + { +- gpointer next; ++ GStaticResource *next; + + do + { +-- +GitLab + + +From 83e48d8ac1fee98059e2305d8909dca26190bddc Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Tue, 17 Nov 2020 10:15:15 +0000 +Subject: [PATCH 29/29] docs: Document not to use `volatile` qualifiers + +Signed-off-by: Philip Withnall + +Fixes: #600 +--- + gio/gdbusconnection.c | 12 ++++++++--- + gio/gdbuserror.c | 3 +++ + glib/gatomic.c | 48 +++++++++++++++++++++++++++++++++++++++++++ + glib/gthread.c | 6 ++++++ + 4 files changed, 66 insertions(+), 3 deletions(-) + +diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c +index 91c365e80..65939a4d2 100644 +--- a/gio/gdbusconnection.c ++++ b/gio/gdbusconnection.c +@@ -1708,7 +1708,9 @@ g_dbus_connection_send_message_unlocked (GDBusConnection *connection, + * will be assigned by @connection and set on @message via + * g_dbus_message_set_serial(). If @out_serial is not %NULL, then the + * serial number used will be written to this location prior to +- * submitting the message to the underlying transport. ++ * submitting the message to the underlying transport. While it has a `volatile` ++ * qualifier, this is a historical artifact and the argument passed to it should ++ * not be `volatile`. + * + * If @connection is closed then the operation will fail with + * %G_IO_ERROR_CLOSED. If @message is not well-formed, +@@ -1979,7 +1981,9 @@ g_dbus_connection_send_message_with_reply_unlocked (GDBusConnection *connect + * will be assigned by @connection and set on @message via + * g_dbus_message_set_serial(). If @out_serial is not %NULL, then the + * serial number used will be written to this location prior to +- * submitting the message to the underlying transport. ++ * submitting the message to the underlying transport. While it has a `volatile` ++ * qualifier, this is a historical artifact and the argument passed to it should ++ * not be `volatile`. + * + * If @connection is closed then the operation will fail with + * %G_IO_ERROR_CLOSED. If @cancellable is canceled, the operation will +@@ -2105,7 +2109,9 @@ send_message_with_reply_sync_cb (GDBusConnection *connection, + * will be assigned by @connection and set on @message via + * g_dbus_message_set_serial(). If @out_serial is not %NULL, then the + * serial number used will be written to this location prior to +- * submitting the message to the underlying transport. ++ * submitting the message to the underlying transport. While it has a `volatile` ++ * qualifier, this is a historical artifact and the argument passed to it should ++ * not be `volatile`. + * + * If @connection is closed then the operation will fail with + * %G_IO_ERROR_CLOSED. If @cancellable is canceled, the operation will +diff --git a/gio/gdbuserror.c b/gio/gdbuserror.c +index b03a33f27..4ad97bb6e 100644 +--- a/gio/gdbuserror.c ++++ b/gio/gdbuserror.c +@@ -177,6 +177,9 @@ g_dbus_error_quark (void) + * + * Helper function for associating a #GError error domain with D-Bus error names. + * ++ * While @quark_volatile has a `volatile` qualifier, this is a historical ++ * artifact and the argument passed to it should not be `volatile`. ++ * + * Since: 2.26 + */ + void +diff --git a/glib/gatomic.c b/glib/gatomic.c +index 67f5ba6b4..0bc67aa35 100644 +--- a/glib/gatomic.c ++++ b/glib/gatomic.c +@@ -105,6 +105,9 @@ + * This call acts as a full compiler and hardware + * memory barrier (before the get). + * ++ * While @atomic has a `volatile` qualifier, this is a historical artifact and ++ * the pointer passed to it should not be `volatile`. ++ * + * Returns: the value of the integer + * + * Since: 2.4 +@@ -125,6 +128,9 @@ gint + * This call acts as a full compiler and hardware + * memory barrier (after the set). + * ++ * While @atomic has a `volatile` qualifier, this is a historical artifact and ++ * the pointer passed to it should not be `volatile`. ++ * + * Since: 2.4 + */ + void +@@ -144,6 +150,9 @@ void + * + * This call acts as a full compiler and hardware memory barrier. + * ++ * While @atomic has a `volatile` qualifier, this is a historical artifact and ++ * the pointer passed to it should not be `volatile`. ++ * + * Since: 2.4 + **/ + void +@@ -163,6 +172,9 @@ void + * + * This call acts as a full compiler and hardware memory barrier. + * ++ * While @atomic has a `volatile` qualifier, this is a historical artifact and ++ * the pointer passed to it should not be `volatile`. ++ * + * Returns: %TRUE if the resultant value is zero + * + * Since: 2.4 +@@ -189,6 +201,9 @@ gboolean + * + * This call acts as a full compiler and hardware memory barrier. + * ++ * While @atomic has a `volatile` qualifier, this is a historical artifact and ++ * the pointer passed to it should not be `volatile`. ++ * + * Returns: %TRUE if the exchange took place + * + * Since: 2.4 +@@ -216,6 +231,9 @@ gboolean + * Before version 2.30, this function did not return a value + * (but g_atomic_int_exchange_and_add() did, and had the same meaning). + * ++ * While @atomic has a `volatile` qualifier, this is a historical artifact and ++ * the pointer passed to it should not be `volatile`. ++ * + * Returns: the value of @atomic before the add, signed + * + * Since: 2.4 +@@ -240,6 +258,9 @@ gint + * Think of this operation as an atomic version of + * `{ tmp = *atomic; *atomic &= val; return tmp; }`. + * ++ * While @atomic has a `volatile` qualifier, this is a historical artifact and ++ * the pointer passed to it should not be `volatile`. ++ * + * Returns: the value of @atomic before the operation, unsigned + * + * Since: 2.30 +@@ -264,6 +285,9 @@ guint + * + * This call acts as a full compiler and hardware memory barrier. + * ++ * While @atomic has a `volatile` qualifier, this is a historical artifact and ++ * the pointer passed to it should not be `volatile`. ++ * + * Returns: the value of @atomic before the operation, unsigned + * + * Since: 2.30 +@@ -288,6 +312,9 @@ guint + * + * This call acts as a full compiler and hardware memory barrier. + * ++ * While @atomic has a `volatile` qualifier, this is a historical artifact and ++ * the pointer passed to it should not be `volatile`. ++ * + * Returns: the value of @atomic before the operation, unsigned + * + * Since: 2.30 +@@ -309,6 +336,9 @@ guint + * This call acts as a full compiler and hardware + * memory barrier (before the get). + * ++ * While @atomic has a `volatile` qualifier, this is a historical artifact and ++ * the pointer passed to it should not be `volatile`. ++ * + * Returns: the value of the pointer + * + * Since: 2.4 +@@ -329,6 +359,9 @@ gpointer + * This call acts as a full compiler and hardware + * memory barrier (after the set). + * ++ * While @atomic has a `volatile` qualifier, this is a historical artifact and ++ * the pointer passed to it should not be `volatile`. ++ * + * Since: 2.4 + **/ + void +@@ -354,6 +387,9 @@ void + * + * This call acts as a full compiler and hardware memory barrier. + * ++ * While @atomic has a `volatile` qualifier, this is a historical artifact and ++ * the pointer passed to it should not be `volatile`. ++ * + * Returns: %TRUE if the exchange took place + * + * Since: 2.4 +@@ -379,6 +415,9 @@ gboolean + * + * This call acts as a full compiler and hardware memory barrier. + * ++ * While @atomic has a `volatile` qualifier, this is a historical artifact and ++ * the pointer passed to it should not be `volatile`. ++ * + * Returns: the value of @atomic before the add, signed + * + * Since: 2.30 +@@ -403,6 +442,9 @@ gssize + * + * This call acts as a full compiler and hardware memory barrier. + * ++ * While @atomic has a `volatile` qualifier, this is a historical artifact and ++ * the pointer passed to it should not be `volatile`. ++ * + * Returns: the value of @atomic before the operation, unsigned + * + * Since: 2.30 +@@ -427,6 +469,9 @@ gsize + * + * This call acts as a full compiler and hardware memory barrier. + * ++ * While @atomic has a `volatile` qualifier, this is a historical artifact and ++ * the pointer passed to it should not be `volatile`. ++ * + * Returns: the value of @atomic before the operation, unsigned + * + * Since: 2.30 +@@ -451,6 +496,9 @@ gsize + * + * This call acts as a full compiler and hardware memory barrier. + * ++ * While @atomic has a `volatile` qualifier, this is a historical artifact and ++ * the pointer passed to it should not be `volatile`. ++ * + * Returns: the value of @atomic before the operation, unsigned + * + * Since: 2.30 +diff --git a/glib/gthread.c b/glib/gthread.c +index 612a9739f..29216d7fd 100644 +--- a/glib/gthread.c ++++ b/glib/gthread.c +@@ -686,6 +686,9 @@ g_once_impl (GOnce *once, + * // use initialization_value here + * ]| + * ++ * While @location has a `volatile` qualifier, this is a historical artifact and ++ * the pointer passed to it should not be `volatile`. ++ * + * Returns: %TRUE if the initialization section should be entered, + * %FALSE and blocks otherwise + * +@@ -725,6 +728,9 @@ gboolean + * releases concurrent threads blocking in g_once_init_enter() on this + * initialization variable. + * ++ * While @location has a `volatile` qualifier, this is a historical artifact and ++ * the pointer passed to it should not be `volatile`. ++ * + * Since: 2.14 + */ + void +-- +GitLab + diff --git a/glib2.spec b/glib2.spec index 649e931..18f81be 100644 --- a/glib2.spec +++ b/glib2.spec @@ -1,6 +1,6 @@ Name: glib2 Version: 2.67.0 -Release: 4%{?dist} +Release: 5%{?dist} Summary: A library of handy utility functions License: LGPLv2+ @@ -14,6 +14,10 @@ Patch0: gnutls-hmac.patch # https://gitlab.gnome.org/GNOME/glib/-/merge_requests/1728 Patch1: 1728.patch +# gcc 11 support: Fix invalid use of volatile objects +# https://gitlab.gnome.org/GNOME/glib/-/merge_requests/1719 +Patch2: 1719.patch + # For gnutls-hmac.patch BuildRequires: pkgconfig(gnutls) @@ -238,6 +242,10 @@ glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || : %{_datadir}/installed-tests %changelog +* Tue Nov 24 2020 Kalev Lember - 2.67.0-5 +- Backport upstream patches to fix invalid use of volatile objects + (gcc 11 support) + * Wed Nov 11 2020 Michael Catanzaro - 2.67.0-4 - Make GnuTLS patch RHEL-specific, and make glib2-static subpackage Fedora-specific