Commit 8d890e27 authored by Thomas Haller's avatar Thomas Haller

core: extend nm_shutdown_wait_obj_*() to support waiting with explicit unregister

The previous to wait-types (NM_SHUTDOWN_WAIT_TYPE_OBJECT and
NM_SHUTDOWN_WAIT_TYPE_CANCELLABLE) both required a GObject/GCancellable,
and the shutdown was automatically unblocked when the object got
destroyed.

Add another wait type NM_SHUTDOWN_WAIT_TYPE_HANDLE, which does not take
an object to wait. Instead, shutdown is indefinitely blocked, until the
user unregisters the handle again. While other wait-types allow to
ignore the handle, this wait-type only makes sense if the user keeps
track of the handle.
parent b6acec0f
......@@ -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);
}
......
......@@ -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,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment