diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c index 19e51cf198..8270d05809 100644 --- a/src/NetworkManagerUtils.c +++ b/src/NetworkManagerUtils.c @@ -981,6 +981,7 @@ _shutdown_waitobj_cb (gpointer user_data, * nm_shutdown_wait_obj_register_full: * @watched_obj: the object to watch. Takes a weak reference on the object * to be notified when it gets destroyed. + * If wait_type is %NM_SHUTDOWN_WAIT_TYPE_HANDLE, this must be %NULL. * @wait_type: whether @watched_obj is just a plain GObject or a GCancellable * that should be cancelled. * @msg_reason: a reason message, for debugging and logging purposes. @@ -1029,6 +1030,8 @@ nm_shutdown_wait_obj_register_full (gpointer watched_obj, g_return_val_if_fail (G_IS_OBJECT (watched_obj), NULL); else if (wait_type == NM_SHUTDOWN_WAIT_TYPE_CANCELLABLE) g_return_val_if_fail (G_IS_CANCELLABLE (watched_obj), NULL); + else if (wait_type == NM_SHUTDOWN_WAIT_TYPE_HANDLE) + g_return_val_if_fail (!watched_obj, NULL); else g_return_val_if_reached (NULL); @@ -1046,7 +1049,8 @@ nm_shutdown_wait_obj_register_full (gpointer watched_obj, .is_cancellable = (wait_type == NM_SHUTDOWN_WAIT_TYPE_CANCELLABLE), }; c_list_link_tail (&_shutdown_waitobj_lst_head, &handle->lst); - g_object_weak_ref (watched_obj, _shutdown_waitobj_cb, handle); + if (watched_obj) + g_object_weak_ref (watched_obj, _shutdown_waitobj_cb, handle); return handle; } @@ -1055,10 +1059,11 @@ nm_shutdown_wait_obj_unregister (NMShutdownWaitObjHandle *handle) { g_return_if_fail (handle); - nm_assert (G_IS_OBJECT (handle->watched_obj)); + nm_assert (!handle->watched_obj || G_IS_OBJECT (handle->watched_obj)); nm_assert (nm_c_list_contains_entry (&_shutdown_waitobj_lst_head, handle, lst)); - g_object_weak_unref (handle->watched_obj, _shutdown_waitobj_cb, handle); + if (handle->watched_obj) + g_object_weak_unref (handle->watched_obj, _shutdown_waitobj_cb, handle); _shutdown_waitobj_unregister (handle); } diff --git a/src/NetworkManagerUtils.h b/src/NetworkManagerUtils.h index 72be1c4cf6..adb1201bf2 100644 --- a/src/NetworkManagerUtils.h +++ b/src/NetworkManagerUtils.h @@ -75,6 +75,10 @@ NMPlatformRoutingRule *nm_ip_routing_rule_to_platform (const NMIPRoutingRule *ru #define NM_SHUTDOWN_TIMEOUT_MS_WATCHDOG 500 typedef enum { + /* There is no watched_obj argument, and the shutdown is delayed until the user + * explicitly calls unregister on the returned handle. */ + NM_SHUTDOWN_WAIT_TYPE_HANDLE, + /* The watched_obj argument is a GObject, and shutdown is delayed until the object * gets destroyed (or unregistered). */ NM_SHUTDOWN_WAIT_TYPE_OBJECT, @@ -102,6 +106,15 @@ nm_shutdown_wait_obj_register_object_full (gpointer watched_obj, #define nm_shutdown_wait_obj_register_object(watched_obj, msg_reason) nm_shutdown_wait_obj_register_object_full((watched_obj), (""msg_reason""), FALSE) +static inline NMShutdownWaitObjHandle * +nm_shutdown_wait_obj_register_handle_full (char *msg_reason, + gboolean free_msg_reason) +{ + return nm_shutdown_wait_obj_register_full (NULL, NM_SHUTDOWN_WAIT_TYPE_HANDLE, msg_reason, free_msg_reason); +} + +#define nm_shutdown_wait_obj_register_handle(msg_reason) nm_shutdown_wait_obj_register_handle_full((""msg_reason""), FALSE) + static inline NMShutdownWaitObjHandle * nm_shutdown_wait_obj_register_cancellable_full (GCancellable *watched_obj, char *msg_reason,