mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-02-04 04:50:30 +01:00
shared: add nm_g_object_ref_set() and nm_clear_g_object()
- nm_clear_g_object() is like g_clear_object() but:
- it returns a boolean value, indicating that something was cleared.
- it includes an nm_assert() to check that the pointer is still
valid.
- it uses typeof() instead of blindly casting the argument.
- nm_g_object_ref_set() combines nm_clear_g_object() and resetting
the pointer to a new object, including taking a reference.
- also returns a boolean, indicating whether something changed.
- it gets the order of operations right: first it increses the
ref-count, before unrefing the old object.
- like nm_clear_g_object() and nm_clear_g_free() it first sets
the destination to NULL, instead of leaving a dangling pointer
for the duraction of the unref/free call.
- fix nm_clear_g_free() not to use a possibly dangling pointer.
Striclty speaking, that is undefined behavior.
This commit is contained in:
parent
19716df23d
commit
959944d623
1 changed files with 52 additions and 3 deletions
|
|
@ -619,6 +619,36 @@ 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.
|
||||
*
|
||||
* It makes sure to first increase the ref-count of @obj, and handles %NULL
|
||||
* @obj correctly.
|
||||
* */
|
||||
#define nm_g_object_ref_set(pp, obj) \
|
||||
({ \
|
||||
typeof (*(pp)) *const _pp = (pp); \
|
||||
typeof (**_pp) *const _obj = (obj); \
|
||||
typeof (**_pp) *_p; \
|
||||
gboolean _changed = FALSE; \
|
||||
\
|
||||
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); \
|
||||
} \
|
||||
*_pp = _obj; \
|
||||
_changed = TRUE; \
|
||||
} \
|
||||
_changed; \
|
||||
})
|
||||
|
||||
/* basically, replaces
|
||||
* g_clear_pointer (&location, g_free)
|
||||
* with
|
||||
|
|
@ -631,13 +661,32 @@ nm_g_object_unref (gpointer obj)
|
|||
#define nm_clear_g_free(pp) \
|
||||
({ \
|
||||
typeof (*(pp)) *_pp = (pp); \
|
||||
typeof (**_pp) *_p = *_pp; \
|
||||
typeof (**_pp) *_p; \
|
||||
gboolean _changed = FALSE; \
|
||||
\
|
||||
if (_p) { \
|
||||
if ( _pp \
|
||||
&& (_p = *_pp)) { \
|
||||
*_pp = NULL; \
|
||||
g_free (_p); \
|
||||
_changed = TRUE; \
|
||||
} \
|
||||
!!_p; \
|
||||
_changed; \
|
||||
})
|
||||
|
||||
#define nm_clear_g_object(pp) \
|
||||
({ \
|
||||
typeof (*(pp)) *_pp = (pp); \
|
||||
typeof (**_pp) *_p; \
|
||||
gboolean _changed = FALSE; \
|
||||
\
|
||||
if ( _pp \
|
||||
&& (_p = *_pp)) { \
|
||||
nm_assert (G_IS_OBJECT (_p)); \
|
||||
*_pp = NULL; \
|
||||
g_object_unref (_p); \
|
||||
_changed = TRUE; \
|
||||
} \
|
||||
_changed; \
|
||||
})
|
||||
|
||||
static inline gboolean
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue