Avoid atomics during construction

During construction, we have exclusive access to
the object, so there is no need to use atomics
for setting or reading the optional_flags member.
This commit is contained in:
Matthias Clasen 2022-06-12 12:00:09 -04:00 committed by Philip Withnall
parent b92f1fcbc5
commit 10a1c16b59

View File

@ -1176,6 +1176,21 @@ object_get_optional_flags (GObject *object)
#endif #endif
} }
/* Variant of object_get_optional_flags for when
* we know that we have exclusive access (during
* construction)
*/
static inline guint
object_get_optional_flags_X (GObject *object)
{
#ifdef HAVE_OPTIONAL_FLAGS
GObjectReal *real = (GObjectReal *)object;
return real->optional_flags;
#else
return 0;
#endif
}
static inline void static inline void
object_set_optional_flags (GObject *object, object_set_optional_flags (GObject *object,
guint flags) guint flags)
@ -1186,13 +1201,29 @@ object_set_optional_flags (GObject *object,
#endif #endif
} }
/* Variant for when we have exclusive access
* (during construction)
*/
static inline void static inline void
object_unset_optional_flags (GObject *object, object_set_optional_flags_X (GObject *object,
guint flags) guint flags)
{ {
#ifdef HAVE_OPTIONAL_FLAGS #ifdef HAVE_OPTIONAL_FLAGS
GObjectReal *real = (GObjectReal *)object; GObjectReal *real = (GObjectReal *)object;
g_atomic_int_and (&real->optional_flags, ~flags); real->optional_flags |= flags;
#endif
}
/* Variant for when we have exclusive access
* (during construction)
*/
static inline void
object_unset_optional_flags_X (GObject *object,
guint flags)
{
#ifdef HAVE_OPTIONAL_FLAGS
GObjectReal *real = (GObjectReal *)object;
real->optional_flags &= ~flags;
#endif #endif
} }
@ -1217,6 +1248,17 @@ _g_object_has_notify_handler (GObject *object)
#endif #endif
} }
static inline gboolean
_g_object_has_notify_handler_X (GObject *object)
{
#ifdef HAVE_OPTIONAL_FLAGS
return CLASS_HAS_NOTIFY (G_OBJECT_GET_CLASS (object)) ||
(object_get_optional_flags_X (object) & OPTIONAL_FLAG_HAS_NOTIFY_HANDLER) != 0;
#else
return TRUE;
#endif
}
void void
_g_object_set_has_signal_handler (GObject *object, _g_object_set_has_signal_handler (GObject *object,
guint signal_id) guint signal_id)
@ -1243,7 +1285,7 @@ static inline void
set_object_in_construction (GObject *object) set_object_in_construction (GObject *object)
{ {
#ifdef HAVE_OPTIONAL_FLAGS #ifdef HAVE_OPTIONAL_FLAGS
object_set_optional_flags (object, OPTIONAL_FLAG_IN_CONSTRUCTION); object_set_optional_flags_X (object, OPTIONAL_FLAG_IN_CONSTRUCTION);
#else #else
g_datalist_id_set_data (&object->qdata, quark_in_construction, object); g_datalist_id_set_data (&object->qdata, quark_in_construction, object);
#endif #endif
@ -1253,7 +1295,7 @@ static inline void
unset_object_in_construction (GObject *object) unset_object_in_construction (GObject *object)
{ {
#ifdef HAVE_OPTIONAL_FLAGS #ifdef HAVE_OPTIONAL_FLAGS
object_unset_optional_flags (object, OPTIONAL_FLAG_IN_CONSTRUCTION); object_unset_optional_flags_X (object, OPTIONAL_FLAG_IN_CONSTRUCTION);
#else #else
g_datalist_id_set_data (&object->qdata, quark_in_construction, NULL); g_datalist_id_set_data (&object->qdata, quark_in_construction, NULL);
#endif #endif
@ -2132,7 +2174,8 @@ g_object_new_with_custom_constructor (GObjectClass *class,
if (CLASS_HAS_PROPS (class)) if (CLASS_HAS_PROPS (class))
{ {
if (_g_object_has_notify_handler (object)) if ((newly_constructed && _g_object_has_notify_handler_X (object)) ||
_g_object_has_notify_handler (object))
{ {
/* This may or may not have been setup in g_object_init(). /* This may or may not have been setup in g_object_init().
* If it hasn't, we do it now. * If it hasn't, we do it now.
@ -2181,7 +2224,7 @@ g_object_new_internal (GObjectClass *class,
{ {
GSList *node; GSList *node;
if (_g_object_has_notify_handler (object)) if (_g_object_has_notify_handler_X (object))
{ {
/* This may or may not have been setup in g_object_init(). /* This may or may not have been setup in g_object_init().
* If it hasn't, we do it now. * If it hasn't, we do it now.