shared: simplify nm_g_object_ref_set()

Also, assign *_pp before unref-ing the old value. Calling
g_object_unref() on the old value, might invoke callbacks
that are out of control of nm_g_object_ref_set(). During
that time, the pointer should already be assigned the new value,
instead of having an intermediate %NULL value. In most cases,
this would of course not matter, but there is no need to let
anyone see an intermediate %NULL value for a moment.

Also, don't use typeof(**_pp), which would not work with opaque
types (like we commonly have).
This commit is contained in:
Thomas Haller 2018-06-14 11:32:56 +02:00
parent fe1f5871c8
commit 9586d2794a

View file

@ -807,8 +807,8 @@ nm_g_object_unref (gpointer obj)
g_object_unref (obj);
}
/* Assigns GObject @obj to destination @pdst, and takes an additional ref.
* The previous value of @pdst is unrefed.
/* Assigns GObject @obj to destination @pp, and takes an additional ref.
* The previous value of @pp is unrefed.
*
* It makes sure to first increase the ref-count of @obj, and handles %NULL
* @obj correctly.
@ -816,22 +816,18 @@ nm_g_object_unref (gpointer obj)
#define nm_g_object_ref_set(pp, obj) \
({ \
typeof (*(pp)) *const _pp = (pp); \
typeof (**_pp) *const _obj = (obj); \
typeof (**_pp) *_p; \
typeof (*_pp) const _obj = (obj); \
typeof (*_pp) _p; \
gboolean _changed = FALSE; \
\
nm_assert (!_pp || !*_pp || G_IS_OBJECT (*_pp)); \
nm_assert (!_obj || G_IS_OBJECT (_obj)); \
\
if ( _pp \
&& ((_p = *_pp) != _obj)) { \
if (_obj) { \
nm_assert (G_IS_OBJECT (_obj)); \
g_object_ref (_obj); \
} \
if (_p) { \
nm_assert (G_IS_OBJECT (_p)); \
*_pp = NULL; \
g_object_unref (_p); \
} \
nm_g_object_ref (_obj); \
*_pp = _obj; \
nm_g_object_unref (_p); \
_changed = TRUE; \
} \
_changed; \