mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-28 16:50:16 +01:00
shared: add nm_utils_invoke_on_timeout()
Add nm_utils_invoke_on_timeout() beside nm_utils_invoke_on_idle(). They are fundamentally similar, except one schedules an idle handler and the other a timeout. Also, use the current g_main_context_get_thread_default() as context instead of the singleton instance. That is a change in behavior, but the only caller of nm_utils_invoke_on_idle() is the daemon, which doesn't use different main contexts. Anyway, to avoid anybody being tripped up by this also change the order of arguments. It anyway seems nicer to first pass the cancellable, and the callback and user data as last arguments. It's more in line with glib's asynchronous methods. Also, in the unlikely case that the cancellable is already cancelled from the start, always schedule an idle action to complete fast.
This commit is contained in:
parent
93b634f1a2
commit
cd5157a0c3
9 changed files with 100 additions and 48 deletions
|
|
@ -3655,9 +3655,9 @@ _nm_utils_user_data_unpack (gpointer user_data, int nargs, ...)
|
|||
typedef struct {
|
||||
gpointer callback_user_data;
|
||||
GCancellable *cancellable;
|
||||
GSource *source;
|
||||
NMUtilsInvokeOnIdleCallback callback;
|
||||
gulong cancelled_id;
|
||||
guint idle_id;
|
||||
} InvokeOnIdleData;
|
||||
|
||||
static gboolean
|
||||
|
|
@ -3665,12 +3665,13 @@ _nm_utils_invoke_on_idle_cb_idle (gpointer user_data)
|
|||
{
|
||||
InvokeOnIdleData *data = user_data;
|
||||
|
||||
data->idle_id = 0;
|
||||
nm_clear_g_signal_handler (data->cancellable, &data->cancelled_id);
|
||||
|
||||
data->callback (data->callback_user_data, data->cancellable);
|
||||
|
||||
nm_g_object_unref (data->cancellable);
|
||||
g_slice_free (InvokeOnIdleData, data);
|
||||
g_source_destroy (data->source);
|
||||
nm_g_slice_free (data);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
|
|
@ -3680,41 +3681,87 @@ _nm_utils_invoke_on_idle_cb_cancelled (GCancellable *cancellable,
|
|||
{
|
||||
/* on cancellation, we invoke the callback synchronously. */
|
||||
nm_clear_g_signal_handler (data->cancellable, &data->cancelled_id);
|
||||
nm_clear_g_source (&data->idle_id);
|
||||
nm_clear_g_source_inst (&data->source);
|
||||
data->callback (data->callback_user_data, data->cancellable);
|
||||
nm_g_object_unref (data->cancellable);
|
||||
g_slice_free (InvokeOnIdleData, data);
|
||||
nm_g_slice_free (data);
|
||||
}
|
||||
|
||||
void
|
||||
nm_utils_invoke_on_idle (NMUtilsInvokeOnIdleCallback callback,
|
||||
gpointer callback_user_data,
|
||||
GCancellable *cancellable)
|
||||
static void
|
||||
_nm_utils_invoke_on_idle_start (gboolean use_timeout,
|
||||
guint timeout_msec,
|
||||
GCancellable *cancellable,
|
||||
NMUtilsInvokeOnIdleCallback callback,
|
||||
gpointer callback_user_data)
|
||||
{
|
||||
InvokeOnIdleData *data;
|
||||
GSource *source;
|
||||
|
||||
g_return_if_fail (callback);
|
||||
|
||||
data = g_slice_new (InvokeOnIdleData);
|
||||
data->callback = callback;
|
||||
data->callback_user_data = callback_user_data;
|
||||
data->cancellable = nm_g_object_ref (cancellable);
|
||||
if ( cancellable
|
||||
&& !g_cancellable_is_cancelled (cancellable)) {
|
||||
/* if we are passed a non-cancelled cancellable, we register to the "cancelled"
|
||||
* signal an invoke the callback synchronously (from the signal handler).
|
||||
*
|
||||
* We don't do that,
|
||||
* - if the cancellable is already cancelled (because we don't want to invoke
|
||||
* the callback synchronously from the caller).
|
||||
* - if we have no cancellable at hand. */
|
||||
data->cancelled_id = g_signal_connect (cancellable,
|
||||
"cancelled",
|
||||
G_CALLBACK (_nm_utils_invoke_on_idle_cb_cancelled),
|
||||
data);
|
||||
} else
|
||||
data->cancelled_id = 0;
|
||||
data->idle_id = g_idle_add (_nm_utils_invoke_on_idle_cb_idle, data);
|
||||
*data = (InvokeOnIdleData) {
|
||||
.callback = callback,
|
||||
.callback_user_data = callback_user_data,
|
||||
.cancellable = nm_g_object_ref (cancellable),
|
||||
.cancelled_id = 0,
|
||||
};
|
||||
|
||||
if (cancellable) {
|
||||
if (g_cancellable_is_cancelled (cancellable)) {
|
||||
/* the cancellable is already cancelled. We ignore the timeout
|
||||
* and always schedule an idle action. */
|
||||
use_timeout = FALSE;
|
||||
} else {
|
||||
/* if we are passed a non-cancelled cancellable, we register to the "cancelled"
|
||||
* signal an invoke the callback synchronously (from the signal handler).
|
||||
*
|
||||
* We don't do that,
|
||||
* - if the cancellable is already cancelled (because we don't want to invoke
|
||||
* the callback synchronously from the caller).
|
||||
* - if we have no cancellable at hand. */
|
||||
data->cancelled_id = g_signal_connect (cancellable,
|
||||
"cancelled",
|
||||
G_CALLBACK (_nm_utils_invoke_on_idle_cb_cancelled),
|
||||
data);
|
||||
}
|
||||
}
|
||||
|
||||
if (use_timeout) {
|
||||
source = nm_g_timeout_source_new (timeout_msec,
|
||||
G_PRIORITY_DEFAULT,
|
||||
_nm_utils_invoke_on_idle_cb_idle,
|
||||
data,
|
||||
NULL);
|
||||
} else {
|
||||
source = nm_g_idle_source_new (G_PRIORITY_DEFAULT,
|
||||
_nm_utils_invoke_on_idle_cb_idle,
|
||||
data,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/* use the current thread default context. */
|
||||
g_source_attach (source,
|
||||
g_main_context_get_thread_default ());
|
||||
|
||||
data->source = source;
|
||||
}
|
||||
|
||||
void
|
||||
nm_utils_invoke_on_idle (GCancellable *cancellable,
|
||||
NMUtilsInvokeOnIdleCallback callback,
|
||||
gpointer callback_user_data)
|
||||
{
|
||||
_nm_utils_invoke_on_idle_start (FALSE, 0, cancellable, callback, callback_user_data);
|
||||
}
|
||||
|
||||
void
|
||||
nm_utils_invoke_on_timeout (guint timeout_msec,
|
||||
GCancellable *cancellable,
|
||||
NMUtilsInvokeOnIdleCallback callback,
|
||||
gpointer callback_user_data)
|
||||
{
|
||||
_nm_utils_invoke_on_idle_start (TRUE, timeout_msec, cancellable, callback, callback_user_data);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -1629,12 +1629,17 @@ void _nm_utils_user_data_unpack (gpointer user_data, int nargs, ...);
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef void (*NMUtilsInvokeOnIdleCallback) (gpointer callback_user_data,
|
||||
typedef void (*NMUtilsInvokeOnIdleCallback) (gpointer user_data,
|
||||
GCancellable *cancellable);
|
||||
|
||||
void nm_utils_invoke_on_idle (NMUtilsInvokeOnIdleCallback callback,
|
||||
gpointer callback_user_data,
|
||||
GCancellable *cancellable);
|
||||
void nm_utils_invoke_on_idle (GCancellable *cancellable,
|
||||
NMUtilsInvokeOnIdleCallback callback,
|
||||
gpointer callback_user_data);
|
||||
|
||||
void nm_utils_invoke_on_timeout (guint timeout_msec,
|
||||
GCancellable *cancellable,
|
||||
NMUtilsInvokeOnIdleCallback callback,
|
||||
gpointer callback_user_data);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
|
|||
|
|
@ -1251,9 +1251,9 @@ _network_server_unregister_bridge (NMBluezManager *self,
|
|||
|
||||
if (r_req_data) {
|
||||
nm_clear_g_cancellable (&r_req_data->int_cancellable);
|
||||
nm_utils_invoke_on_idle (_network_server_unregister_bridge_complete_on_idle_cb,
|
||||
nm_utils_user_data_pack (r_req_data, g_strdup (reason)),
|
||||
r_req_data->ext_cancellable);
|
||||
nm_utils_invoke_on_idle (r_req_data->ext_cancellable,
|
||||
_network_server_unregister_bridge_complete_on_idle_cb,
|
||||
nm_utils_user_data_pack (r_req_data, g_strdup (reason)));
|
||||
}
|
||||
|
||||
_nm_device_bridge_notify_unregister_bt_nap (device, reason);
|
||||
|
|
|
|||
|
|
@ -310,7 +310,7 @@ deactivate_async (NMDevice *device,
|
|||
nm_device_get_iface (device))) {
|
||||
_LOGT (LOGD_CORE, "deactivate: link not present, proceeding");
|
||||
nm_device_update_from_platform_link (NM_DEVICE (self), NULL);
|
||||
nm_utils_invoke_on_idle (deactivate_cb_on_idle, data, cancellable);
|
||||
nm_utils_invoke_on_idle (cancellable, deactivate_cb_on_idle, data);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -507,7 +507,7 @@ deactivate_async (NMDevice *device,
|
|||
user_data = nm_utils_user_data_pack (g_object_ref (self), callback, callback_user_data);
|
||||
|
||||
if (!priv->dbus_obj) {
|
||||
nm_utils_invoke_on_idle (disconnect_cb_on_idle, user_data, cancellable);
|
||||
nm_utils_invoke_on_idle (cancellable, disconnect_cb_on_idle, user_data);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -684,7 +684,7 @@ deactivate_async (NMDevice *device,
|
|||
|
||||
user_data = nm_utils_user_data_pack (g_object_ref (self), callback, callback_user_data);
|
||||
if (!priv->sup_iface) {
|
||||
nm_utils_invoke_on_idle (disconnect_cb_on_idle, user_data, cancellable);
|
||||
nm_utils_invoke_on_idle (cancellable, disconnect_cb_on_idle, user_data);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1254,9 +1254,9 @@ disconnect (NMModem *modem,
|
|||
/* Already cancelled or no simple-iface? We are done. */
|
||||
if ( !ctx->self->_priv.simple_iface
|
||||
|| g_cancellable_is_cancelled (cancellable)) {
|
||||
nm_utils_invoke_on_idle (disconnect_context_complete_on_idle,
|
||||
ctx,
|
||||
cancellable);
|
||||
nm_utils_invoke_on_idle (cancellable,
|
||||
disconnect_context_complete_on_idle,
|
||||
ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -211,9 +211,9 @@ disconnect (NMModem *modem,
|
|||
|
||||
if ( state != NM_MODEM_STATE_CONNECTED
|
||||
|| g_cancellable_is_cancelled (cancellable)) {
|
||||
nm_utils_invoke_on_idle (disconnect_context_complete_on_idle,
|
||||
ctx,
|
||||
cancellable);
|
||||
nm_utils_invoke_on_idle (cancellable,
|
||||
disconnect_context_complete_on_idle,
|
||||
ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5131,9 +5131,9 @@ sysctl_set_async (NMPlatform *platform,
|
|||
callback,
|
||||
data,
|
||||
error);
|
||||
nm_utils_invoke_on_idle (sysctl_set_async_return_idle,
|
||||
packed,
|
||||
cancellable);
|
||||
nm_utils_invoke_on_idle (cancellable,
|
||||
sysctl_set_async_return_idle,
|
||||
packed);
|
||||
return;
|
||||
}
|
||||
} else
|
||||
|
|
@ -7390,7 +7390,7 @@ out_idle:
|
|||
g_steal_pointer (&error),
|
||||
callback,
|
||||
data);
|
||||
nm_utils_invoke_on_idle (sriov_idle_cb, packed, cancellable);
|
||||
nm_utils_invoke_on_idle (cancellable, sriov_idle_cb, packed);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue