summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2018-10-17 13:03:57 +0200
committerThomas Haller <thaller@redhat.com>2018-10-17 13:03:57 +0200
commitfd7115eeed527c92925b3b176add81d9a3605455 (patch)
treef3f59da05103cc52c2e364e59de8b404a7f14ebc
parent09719bc479b63c8e5fef3950e980b263aca7eff5 (diff)
parent47146b4be3300308967605040612b6207ddb5057 (diff)
downloadNetworkManager-fd7115eeed527c92925b3b176add81d9a3605455.tar.gz
core: merge branch 'th/no-gasyncresult'
https://github.com/NetworkManager/NetworkManager/pull/227
-rw-r--r--libnm-core/nm-core-internal.h9
-rw-r--r--libnm-core/nm-dbus-utils.c89
-rw-r--r--shared/nm-utils/nm-shared-utils.c67
-rw-r--r--shared/nm-utils/nm-shared-utils.h9
-rw-r--r--src/devices/adsl/nm-device-adsl.c2
-rw-r--r--src/devices/bluetooth/nm-bluez-device.c180
-rw-r--r--src/devices/bluetooth/nm-bluez-device.h15
-rw-r--r--src/devices/bluetooth/nm-bluez5-dun.c7
-rw-r--r--src/devices/bluetooth/nm-bluez5-dun.h3
-rw-r--r--src/devices/bluetooth/nm-device-bt.c65
-rw-r--r--src/devices/nm-device-ethernet.c2
-rw-r--r--src/devices/nm-device-ppp.c2
-rw-r--r--src/devices/nm-device.c38
-rw-r--r--src/devices/nm-device.h9
-rw-r--r--src/devices/wifi/nm-device-iwd.c70
-rw-r--r--src/devices/wwan/libnm-wwan.ver1
-rw-r--r--src/devices/wwan/nm-device-modem.c44
-rw-r--r--src/devices/wwan/nm-modem-broadband.c85
-rw-r--r--src/devices/wwan/nm-modem-ofono.c89
-rw-r--r--src/devices/wwan/nm-modem.c207
-rw-r--r--src/devices/wwan/nm-modem.h22
-rw-r--r--src/ppp/nm-ppp-manager-call.c3
-rw-r--r--src/ppp/nm-ppp-manager-call.h1
-rw-r--r--src/ppp/nm-ppp-manager.c39
-rw-r--r--src/ppp/nm-ppp-plugin-api.h1
25 files changed, 590 insertions, 469 deletions
diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h
index 8b36bbd27b..22c85cd769 100644
--- a/libnm-core/nm-core-internal.h
+++ b/libnm-core/nm-core-internal.h
@@ -305,6 +305,10 @@ void _nm_dbus_errors_init (void);
extern gboolean _nm_utils_is_manager_process;
+gboolean _nm_dbus_typecheck_response (GVariant *response,
+ const GVariantType *reply_type,
+ GError **error);
+
gulong _nm_dbus_signal_connect_data (GDBusProxy *proxy,
const char *signal_name,
const GVariantType *signature,
@@ -329,6 +333,11 @@ GVariant *_nm_dbus_proxy_call_sync (GDBusProxy *proxy,
GCancellable *cancellable,
GError **error);
+GVariant * _nm_dbus_connection_call_finish (GDBusConnection *dbus_connection,
+ GAsyncResult *result,
+ const GVariantType *reply_type,
+ GError **error);
+
gboolean _nm_dbus_error_has_name (GError *error,
const char *dbus_error_name);
diff --git a/libnm-core/nm-dbus-utils.c b/libnm-core/nm-dbus-utils.c
index 25af7c9964..69f4bb2f8a 100644
--- a/libnm-core/nm-dbus-utils.c
+++ b/libnm-core/nm-dbus-utils.c
@@ -174,23 +174,35 @@ _nm_dbus_signal_connect_data (GDBusProxy *proxy,
* Returns: the signal handler ID, as with _nm_signal_connect_data().
*/
-static void
-typecheck_response (GVariant **response,
- const GVariantType *reply_type,
- GError **error)
+/**
+ * _nm_dbus_typecheck_response:
+ * @response: the #GVariant response to check.
+ * @reply_type: the expected reply type. It may be %NULL to perform no
+ * checking.
+ * @error: (allow-none): the error in case the @reply_type does not match.
+ *
+ * Returns: %TRUE, if @response is of the expected @reply_type.
+ */
+gboolean
+_nm_dbus_typecheck_response (GVariant *response,
+ const GVariantType *reply_type,
+ GError **error)
{
- if ( *response
- && reply_type
- && !g_variant_is_of_type (*response, reply_type)) {
- /* This is the same error code that g_dbus_connection_call() returns if
- * @reply_type doesn't match.
- */
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
- _("Method returned type '%s', but expected '%s'"),
- g_variant_get_type_string (*response),
- g_variant_type_peek_string (reply_type));
- g_clear_pointer (response, g_variant_unref);
- }
+ g_return_val_if_fail (response, FALSE);
+
+ if (!reply_type)
+ return TRUE;
+ if (g_variant_is_of_type (response, reply_type))
+ return TRUE;
+
+ /* This is the same error code that g_dbus_connection_call() returns if
+ * @reply_type doesn't match.
+ */
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
+ _("Method returned type '%s', but expected '%s'"),
+ g_variant_get_type_string (response),
+ g_variant_type_peek_string (reply_type));
+ return FALSE;
}
/**
@@ -215,11 +227,15 @@ _nm_dbus_proxy_call_finish (GDBusProxy *proxy,
const GVariantType *reply_type,
GError **error)
{
- GVariant *ret;
+ GVariant *variant;
- ret = g_dbus_proxy_call_finish (proxy, res, error);
- typecheck_response (&ret, reply_type, error);
- return ret;
+ variant = g_dbus_proxy_call_finish (proxy,
+ res,
+ error);
+ if ( variant
+ && !_nm_dbus_typecheck_response (variant, reply_type, error))
+ nm_clear_pointer (&variant, g_variant_unref);
+ return variant;
}
/**
@@ -253,13 +269,34 @@ _nm_dbus_proxy_call_sync (GDBusProxy *proxy,
GCancellable *cancellable,
GError **error)
{
- GVariant *ret;
+ GVariant *variant;
+
+ variant = g_dbus_proxy_call_sync (proxy,
+ method_name,
+ parameters,
+ flags,
+ timeout_msec,
+ cancellable,
+ error);
+ if ( variant
+ && !_nm_dbus_typecheck_response (variant, reply_type, error))
+ nm_clear_pointer (&variant, g_variant_unref);
+ return variant;
+}
+
+GVariant *
+_nm_dbus_connection_call_finish (GDBusConnection *dbus_connection,
+ GAsyncResult *result,
+ const GVariantType *reply_type,
+ GError **error)
+{
+ GVariant *variant;
- ret = g_dbus_proxy_call_sync (proxy, method_name, parameters,
- flags, timeout_msec,
- cancellable, error);
- typecheck_response (&ret, reply_type, error);
- return ret;
+ variant = g_dbus_connection_call_finish (dbus_connection, result, error);
+ if ( variant
+ && !_nm_dbus_typecheck_response (variant, reply_type, error))
+ nm_clear_pointer (&variant, g_variant_unref);
+ return variant;
}
/**
diff --git a/shared/nm-utils/nm-shared-utils.c b/shared/nm-utils/nm-shared-utils.c
index 2ace309841..c41b5e68c2 100644
--- a/shared/nm-utils/nm-shared-utils.c
+++ b/shared/nm-utils/nm-shared-utils.c
@@ -2055,3 +2055,70 @@ _nm_utils_unescape_spaces (char *str)
}
#undef IS_SPACE
+
+/*****************************************************************************/
+
+typedef struct {
+ gpointer callback_user_data;
+ GCancellable *cancellable;
+ NMUtilsInvokeOnIdleCallback callback;
+ gulong cancelled_id;
+ guint idle_id;
+} InvokeOnIdleData;
+
+static gboolean
+_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);
+ return G_SOURCE_REMOVE;
+}
+
+static void
+_nm_utils_invoke_on_idle_cb_cancelled (GCancellable *cancellable,
+ InvokeOnIdleData *data)
+{
+ /* on cancellation, we invoke the callback synchronously. */
+ nm_clear_g_signal_handler (data->cancellable, &data->cancelled_id);
+ nm_clear_g_source (&data->idle_id);
+ data->callback (data->callback_user_data, data->cancellable);
+ nm_g_object_unref (data->cancellable);
+ g_slice_free (InvokeOnIdleData, data);
+}
+
+void
+nm_utils_invoke_on_idle (NMUtilsInvokeOnIdleCallback callback,
+ gpointer callback_user_data,
+ GCancellable *cancellable)
+{
+ InvokeOnIdleData *data;
+
+ 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);
+}
diff --git a/shared/nm-utils/nm-shared-utils.h b/shared/nm-utils/nm-shared-utils.h
index fb37535d76..7ee76799bd 100644
--- a/shared/nm-utils/nm-shared-utils.h
+++ b/shared/nm-utils/nm-shared-utils.h
@@ -909,4 +909,13 @@ void _nm_utils_user_data_unpack (gpointer user_data, int nargs, ...);
const char *_nm_utils_escape_spaces (const char *str, char **to_free);
char *_nm_utils_unescape_spaces (char *str);
+/*****************************************************************************/
+
+typedef void (*NMUtilsInvokeOnIdleCallback) (gpointer callback_user_data,
+ GCancellable *cancellable);
+
+void nm_utils_invoke_on_idle (NMUtilsInvokeOnIdleCallback callback,
+ gpointer callback_user_data,
+ GCancellable *cancellable);
+
#endif /* __NM_SHARED_UTILS_H__ */
diff --git a/src/devices/adsl/nm-device-adsl.c b/src/devices/adsl/nm-device-adsl.c
index c9984f5135..9cec81920f 100644
--- a/src/devices/adsl/nm-device-adsl.c
+++ b/src/devices/adsl/nm-device-adsl.c
@@ -523,7 +523,7 @@ adsl_cleanup (NMDeviceAdsl *self)
if (priv->ppp_manager) {
g_signal_handlers_disconnect_by_func (priv->ppp_manager, G_CALLBACK (ppp_state_changed), self);
g_signal_handlers_disconnect_by_func (priv->ppp_manager, G_CALLBACK (ppp_ip4_config), self);
- nm_ppp_manager_stop (priv->ppp_manager, NULL, NULL);
+ nm_ppp_manager_stop (priv->ppp_manager, NULL, NULL, NULL);
g_clear_object (&priv->ppp_manager);
}
diff --git a/src/devices/bluetooth/nm-bluez-device.c b/src/devices/bluetooth/nm-bluez-device.c
index b722f692ce..8e2a96b78f 100644
--- a/src/devices/bluetooth/nm-bluez-device.c
+++ b/src/devices/bluetooth/nm-bluez-device.c
@@ -451,6 +451,9 @@ nm_bluez_device_disconnect (NMBluezDevice *self)
g_return_if_fail (priv->dbus_connection);
+ /* FIXME: if we are in the process of connecting and cancel the
+ * connection attempt, we must complete the pending connect request.
+ * However, we must also ensure that we don't leave a connected device. */
if (priv->connection_bt_type == NM_BT_CAPABILITY_DUN) {
if (priv->bluez_version == 4) {
/* Can't pass a NULL interface name through dbus to bluez, so just
@@ -496,76 +499,109 @@ out:
}
static void
-bluez_connect_cb (GDBusConnection *dbus_connection,
+_connect_complete (NMBluezDevice *self,
+ const char *device,
+ NMBluezDeviceConnectCallback callback,
+ gpointer callback_user_data,
+ GError *error)
+{
+ NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self);
+
+ nm_assert ((device || error) && !(device && error));
+
+ if ( device
+ && priv->bluez_version == 5) {
+ priv->connected = TRUE;
+ _notify (self, PROP_CONNECTED);
+ }
+
+ if (callback)
+ callback (self, device, error, callback_user_data);
+}
+
+static void
+_connect_cb (GObject *source_object,
GAsyncResult *res,
gpointer user_data)
{
- GSimpleAsyncResult *result = G_SIMPLE_ASYNC_RESULT (user_data);
- GObject *result_object = g_async_result_get_source_object (G_ASYNC_RESULT (result));
- NMBluezDevice *self = NM_BLUEZ_DEVICE (result_object);
- NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self);
- GError *error = NULL;
- char *device;
- GVariant *variant;
+ gs_unref_object NMBluezDevice *self = NULL;
+ NMBluezDevicePrivate *priv;
+ NMBluezDeviceConnectCallback callback;
+ gpointer callback_user_data;
+ gs_free_error GError *error = NULL;
+ char *device = NULL;
+ gs_unref_variant GVariant *variant = NULL;
- variant = g_dbus_connection_call_finish (dbus_connection, res, &error);
+ nm_utils_user_data_unpack (user_data, &self, &callback, &callback_user_data);
- if (!variant) {
- g_simple_async_result_take_error (result, error);
- } else {
- g_variant_get (variant, "(s)", &device);
+ priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self);
- g_simple_async_result_set_op_res_gpointer (result,
- g_strdup (device),
- g_free);
+ variant = _nm_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object), res, G_VARIANT_TYPE ("(s)"), &error);
+ if (variant) {
+ g_variant_get (variant, "(s)", &device);
priv->b4_iface = device;
- g_variant_unref (variant);
}
- g_simple_async_result_complete (result);
- g_object_unref (result);
- g_object_unref (result_object);
+ _connect_complete (self, device, callback, callback_user_data, error);
}
#if WITH_BLUEZ5_DUN
static void
-bluez5_dun_connect_cb (NMBluez5DunContext *context,
- const char *device,
- GError *error,
- gpointer user_data)
+_connect_cb_bluez5_dun (NMBluez5DunContext *context,
+ const char *device,
+ GError *error,
+ gpointer user_data)
{
- GSimpleAsyncResult *result = G_SIMPLE_ASYNC_RESULT (user_data);
+ gs_unref_object NMBluezDevice *self = NULL;
+ gs_unref_object GCancellable *cancellable = NULL;
+ NMBluezDeviceConnectCallback callback;
+ gpointer callback_user_data;
+ gs_free_error GError *cancelled_error = NULL;
- if (error) {
- g_simple_async_result_take_error (result, error);
- } else {
- g_simple_async_result_set_op_res_gpointer (result,
- g_strdup (device),
- g_free);
- }
+ nm_utils_user_data_unpack (user_data, &self, &cancellable, &callback, &callback_user_data);
+
+ /* FIXME(shutdown): the async operation nm_bluez5_dun_connect() should be cancellable.
+ * Fake it here. */
+ if (g_cancellable_set_error_if_cancelled (cancellable, &cancelled_error))
+ error = cancelled_error;
- g_simple_async_result_complete (result);
- g_object_unref (result);
+ _connect_complete (self, device, callback, callback_user_data, error);
}
-#endif
+#else /* WITH_BLUEZ5_DUN */
+static void
+_connect_cb_bluez5_dun_idle_no_b5 (gpointer user_data,
+ GCancellable *cancellable)
+{
+ gs_unref_object NMBluezDevice *self = NULL;
+ NMBluezDeviceConnectCallback callback;
+ gpointer callback_user_data;
+ gs_free_error GError *error = NULL;
+
+ nm_utils_user_data_unpack (user_data, &self, &callback, &callback_user_data);
+
+ if (!g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+ g_set_error (&error,
+ NM_BT_ERROR,
+ NM_BT_ERROR_DUN_CONNECT_FAILED,
+ "NetworkManager built without support for Bluez 5");
+ }
+ callback (self, NULL, error, callback_user_data);
+}
+#endif /* WITH_BLUEZ5_DUN */
void
nm_bluez_device_connect_async (NMBluezDevice *self,
NMBluetoothCapabilities connection_bt_type,
- GAsyncReadyCallback callback,
- gpointer user_data)
+ GCancellable *cancellable,
+ NMBluezDeviceConnectCallback callback,
+ gpointer callback_user_data)
{
- GSimpleAsyncResult *simple;
NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self);
const char *dbus_iface = NULL;
const char *connect_type = NULL;
g_return_if_fail (priv->capabilities & connection_bt_type & (NM_BT_CAPABILITY_DUN | NM_BT_CAPABILITY_NAP));
- simple = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- nm_bluez_device_connect_async);
priv->connection_bt_type = connection_bt_type;
if (connection_bt_type == NM_BT_CAPABILITY_NAP) {
@@ -582,19 +618,29 @@ nm_bluez_device_connect_async (NMBluezDevice *self,
#if WITH_BLUEZ5_DUN
if (priv->b5_dun_context == NULL)
priv->b5_dun_context = nm_bluez5_dun_new (priv->adapter_address, priv->address);
- nm_bluez5_dun_connect (priv->b5_dun_context, bluez5_dun_connect_cb, simple);
+ nm_bluez5_dun_connect (priv->b5_dun_context,
+ _connect_cb_bluez5_dun,
+ nm_utils_user_data_pack (g_object_ref (self),
+ nm_g_object_ref (cancellable),
+ callback,
+ callback_user_data));
#else
- g_simple_async_result_set_error (simple,
- NM_BT_ERROR,
- NM_BT_ERROR_DUN_CONNECT_FAILED,
- "NetworkManager built without support for Bluez 5");
- g_simple_async_result_complete (simple);
+ if (callback) {
+ nm_utils_invoke_on_idle (_connect_cb_bluez5_dun_idle_no_b5,
+ nm_utils_user_data_pack (g_object_ref (self),
+ callback,
+ callback_user_data),
+ cancellable);
+ }
#endif
return;
}
} else
- g_assert_not_reached ();
+ g_return_if_reached ();
+ /* FIXME: we need to remember that a connect is in progress.
+ * So, if the request gets cancelled, that we disconnect the
+ * connection that was established in the meantime. */
g_dbus_connection_call (priv->dbus_connection,
NM_BLUEZ_SERVICE,
priv->path,
@@ -604,37 +650,11 @@ nm_bluez_device_connect_async (NMBluezDevice *self,
NULL,
G_DBUS_CALL_FLAGS_NONE,
20000,
- NULL,
- (GAsyncReadyCallback) bluez_connect_cb,
- simple);
-}
-
-const char *
-nm_bluez_device_connect_finish (NMBluezDevice *self,
- GAsyncResult *result,
- GError **error)
-{
- NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self);
- GSimpleAsyncResult *simple;
- const char *device;
-
- g_return_val_if_fail (g_simple_async_result_is_valid (result,
- G_OBJECT (self),
- nm_bluez_device_connect_async),
- NULL);
-
- simple = (GSimpleAsyncResult *) result;
-
- if (g_simple_async_result_propagate_error (simple, error))
- return NULL;
-
- device = (const char *) g_simple_async_result_get_op_res_gpointer (simple);
- if (device && priv->bluez_version == 5) {
- priv->connected = TRUE;
- _notify (self, PROP_CONNECTED);
- }
-
- return device;
+ cancellable,
+ _connect_cb,
+ nm_utils_user_data_pack (g_object_ref (self),
+ callback,
+ callback_user_data));
}
/*****************************************************************************/
diff --git a/src/devices/bluetooth/nm-bluez-device.h b/src/devices/bluetooth/nm-bluez-device.h
index f8a1872f2e..d2d0beb016 100644
--- a/src/devices/bluetooth/nm-bluez-device.h
+++ b/src/devices/bluetooth/nm-bluez-device.h
@@ -66,16 +66,17 @@ guint32 nm_bluez_device_get_capabilities (NMBluezDevice *self);
gboolean nm_bluez_device_get_connected (NMBluezDevice *self);
+typedef void (*NMBluezDeviceConnectCallback) (NMBluezDevice *self,
+ const char *device,
+ GError *error,
+ gpointer user_data);
+
void
nm_bluez_device_connect_async (NMBluezDevice *self,
NMBluetoothCapabilities connection_bt_type,
- GAsyncReadyCallback callback,
- gpointer user_data);
-
-const char *
-nm_bluez_device_connect_finish (NMBluezDevice *self,
- GAsyncResult *result,
- GError **error);
+ GCancellable *cancellable,
+ NMBluezDeviceConnectCallback callback,
+ gpointer callback_user_data);
void
nm_bluez_device_disconnect (NMBluezDevice *self);
diff --git a/src/devices/bluetooth/nm-bluez5-dun.c b/src/devices/bluetooth/nm-bluez5-dun.c
index ca09b276e7..32f8da65eb 100644
--- a/src/devices/bluetooth/nm-bluez5-dun.c
+++ b/src/devices/bluetooth/nm-bluez5-dun.c
@@ -342,13 +342,14 @@ nm_bluez5_dun_connect (NMBluez5DunContext *context,
if (context->rfcomm_channel != -1) {
nm_log_dbg (LOGD_BT, "(%s): channel number on device %s cached: %d",
- context->src_str, context->dst_str, context->rfcomm_channel);
+ context->src_str, context->dst_str, context->rfcomm_channel);
+ /* FIXME: don't invoke the callback synchronously. */
dun_connect (context);
return;
}
nm_log_dbg (LOGD_BT, "(%s): starting channel number discovery for device %s",
- context->src_str, context->dst_str);
+ context->src_str, context->dst_str);
context->sdp_session = sdp_connect (&context->src, &context->dst, SDP_NON_BLOCKING);
if (!context->sdp_session) {
@@ -358,10 +359,12 @@ nm_bluez5_dun_connect (NMBluez5DunContext *context,
error = g_error_new (NM_BT_ERROR, NM_BT_ERROR_DUN_CONNECT_FAILED,
"Failed to connect to the SDP server: (%d) %s",
err, strerror (err));
+ /* FIXME: don't invoke the callback synchronously. */
context->callback (context, NULL, error, context->user_data);
return;
}
+ /* FIXME(shutdown): make connect cancellable. */
channel = g_io_channel_unix_new (sdp_get_socket (context->sdp_session));
context->sdp_watch_id = g_io_add_watch (channel,
G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
diff --git a/src/devices/bluetooth/nm-bluez5-dun.h b/src/devices/bluetooth/nm-bluez5-dun.h
index 124c1a05b0..b75e4399a7 100644
--- a/src/devices/bluetooth/nm-bluez5-dun.h
+++ b/src/devices/bluetooth/nm-bluez5-dun.h
@@ -32,7 +32,8 @@ NMBluez5DunContext *nm_bluez5_dun_new (const char *adapter,
const char *remote);
void nm_bluez5_dun_connect (NMBluez5DunContext *context,
- NMBluez5DunFunc callback, gpointer user_data);
+ NMBluez5DunFunc callback,
+ gpointer user_data);
/* Clean up connection resources */
void nm_bluez5_dun_cleanup (NMBluez5DunContext *context);
diff --git a/src/devices/bluetooth/nm-device-bt.c b/src/devices/bluetooth/nm-device-bt.c
index 1f650d339f..b05c569beb 100644
--- a/src/devices/bluetooth/nm-device-bt.c
+++ b/src/devices/bluetooth/nm-device-bt.c
@@ -78,7 +78,9 @@ typedef struct {
char *rfcomm_iface;
NMModem *modem;
- guint32 timeout_id;
+ guint timeout_id;
+
+ GCancellable *cancellable;
guint32 bt_type; /* BT type of the current connection */
} NMDeviceBtPrivate;
@@ -672,6 +674,7 @@ component_added (NMDevice *device, GObject *component)
/* Got the modem */
nm_clear_g_source (&priv->timeout_id);
+ nm_clear_g_cancellable (&priv->cancellable);
/* Can only accept the modem in stage2, but since the interface matched
* what we were expecting, don't let anything else claim the modem either.
@@ -715,8 +718,11 @@ static gboolean
modem_find_timeout (gpointer user_data)
{
NMDeviceBt *self = NM_DEVICE_BT (user_data);
+ NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (self);
+
+ priv->timeout_id = 0;
+ nm_clear_g_cancellable (&priv->cancellable);
- NM_DEVICE_BT_GET_PRIVATE (self)->timeout_id = 0;
nm_device_state_changed (NM_DEVICE (self),
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_MODEM_NOT_FOUND);
@@ -738,8 +744,8 @@ check_connect_continue (NMDeviceBt *self)
"Activation: (bluetooth) Stage 2 of 5 (Device Configure) successful. Will connect via %s.",
dun ? "DUN" : (pan ? "PAN" : "unknown"));
- /* Kill the connect timeout since we're connected now */
nm_clear_g_source (&priv->timeout_id);
+ nm_clear_g_cancellable (&priv->cancellable);
if (pan) {
/* Bluez says we're connected now. Start IP config. */
@@ -755,25 +761,25 @@ check_connect_continue (NMDeviceBt *self)
}
static void
-bluez_connect_cb (GObject *object,
- GAsyncResult *res,
- void *user_data)
+bluez_connect_cb (NMBluezDevice *bt_device,
+ const char *device_name,
+ GError *error,
+ gpointer user_data)
{
- gs_unref_object NMDeviceBt *self = NM_DEVICE_BT (user_data);
+ gs_unref_object NMDeviceBt *self = user_data;
NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (self);
- GError *error = NULL;
- const char *device;
- device = nm_bluez_device_connect_finish (NM_BLUEZ_DEVICE (object),
- res, &error);
+ if (nm_utils_error_is_cancelled (error, FALSE))
+ return;
+
+ nm_clear_g_source (&priv->timeout_id);
+ g_clear_object (&priv->cancellable);
if (!nm_device_is_activating (NM_DEVICE (self)))
return;
- if (!device) {
+ if (!device_name) {
_LOGW (LOGD_BT, "Error connecting with bluez: %s", error->message);
- g_clear_error (&error);
-
nm_device_state_changed (NM_DEVICE (self),
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_BT_FAILED);
@@ -782,10 +788,10 @@ bluez_connect_cb (GObject *object,
if (priv->bt_type == NM_BT_CAPABILITY_DUN) {
g_free (priv->rfcomm_iface);
- priv->rfcomm_iface = g_strdup (device);
+ priv->rfcomm_iface = g_strdup (device_name);
} else if (priv->bt_type == NM_BT_CAPABILITY_NAP) {
- if (!nm_device_set_ip_iface (NM_DEVICE (self), device)) {
- _LOGW (LOGD_BT, "Error connecting with bluez: cannot find device %s", device);
+ if (!nm_device_set_ip_iface (NM_DEVICE (self), device_name)) {
+ _LOGW (LOGD_BT, "Error connecting with bluez: cannot find device %s", device_name);
nm_device_state_changed (NM_DEVICE (self),
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_BT_FAILED);
@@ -843,10 +849,13 @@ static gboolean
bt_connect_timeout (gpointer user_data)
{
NMDeviceBt *self = NM_DEVICE_BT (user_data);
+ NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (self);
_LOGD (LOGD_BT, "initial connection timed out");
- NM_DEVICE_BT_GET_PRIVATE (self)->timeout_id = 0;
+ priv->timeout_id = 0;
+ nm_clear_g_cancellable (&priv->cancellable);
+
nm_device_state_changed (NM_DEVICE (self),
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_BT_FAILED);
@@ -876,13 +885,17 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason)
_LOGD (LOGD_BT, "requesting connection to the device");
- /* Connect to the BT device */
- nm_bluez_device_connect_async (priv->bt_device,
- priv->bt_type & (NM_BT_CAPABILITY_DUN | NM_BT_CAPABILITY_NAP),
- bluez_connect_cb, g_object_ref (device));
-
nm_clear_g_source (&priv->timeout_id);
+ nm_clear_g_cancellable (&priv->cancellable);
+
priv->timeout_id = g_timeout_add_seconds (30, bt_connect_timeout, device);
+ priv->cancellable = g_cancellable_new ();
+
+ nm_bluez_device_connect_async (priv->bt_device,
+ priv->bt_type & (NM_BT_CAPABILITY_DUN | NM_BT_CAPABILITY_NAP),
+ priv->cancellable,
+ bluez_connect_cb,
+ g_object_ref (self));
return NM_ACT_STAGE_RETURN_POSTPONE;
}
@@ -925,6 +938,9 @@ deactivate (NMDevice *device)
priv->have_iface = FALSE;
priv->connected = FALSE;
+ nm_clear_g_source (&priv->timeout_id);
+ nm_clear_g_cancellable (&priv->cancellable);
+
if (priv->bt_type == NM_BT_CAPABILITY_DUN) {
if (priv->modem) {
nm_modem_deactivate (priv->modem, device);
@@ -942,8 +958,6 @@ deactivate (NMDevice *device)
if (priv->bt_type != NM_BT_CAPABILITY_NONE)
nm_bluez_device_disconnect (priv->bt_device);
- nm_clear_g_source (&priv->timeout_id);
-
priv->bt_type = NM_BT_CAPABILITY_NONE;
g_free (priv->rfcomm_iface);
@@ -1128,6 +1142,7 @@ dispose (GObject *object)
NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE ((NMDeviceBt *) object);
nm_clear_g_source (&priv->timeout_id);
+ nm_clear_g_cancellable (&priv->cancellable);
g_signal_handlers_disconnect_matched (priv->bt_device, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, object);
diff --git a/src/devices/nm-device-ethernet.c b/src/devices/nm-device-ethernet.c
index 0fb8fea42c..1587a2a343 100644
--- a/src/devices/nm-device-ethernet.c
+++ b/src/devices/nm-device-ethernet.c
@@ -1347,7 +1347,7 @@ deactivate (NMDevice *device)
nm_clear_g_source (&priv->pppoe_wait_id);
if (priv->ppp_manager) {
- nm_ppp_manager_stop (priv->ppp_manager, NULL, NULL);
+ nm_ppp_manager_stop (priv->ppp_manager, NULL, NULL, NULL);
g_clear_object (&priv->ppp_manager);
}
diff --git a/src/devices/nm-device-ppp.c b/src/devices/nm-device-ppp.c
index 74b4d710ca..3a3f9054a1 100644
--- a/src/devices/nm-device-ppp.c
+++ b/src/devices/nm-device-ppp.c
@@ -221,7 +221,7 @@ deactivate (NMDevice *device)
NMDevicePppPrivate *priv = NM_DEVICE_PPP_GET_PRIVATE (self);
if (priv->ppp_manager) {
- nm_ppp_manager_stop (priv->ppp_manager, NULL, NULL);
+ nm_ppp_manager_stop (priv->ppp_manager, NULL, NULL, NULL);
g_clear_object (&priv->ppp_manager);
}
}
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 7a9f03800a..ce21803bfa 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -14537,30 +14537,25 @@ ip6_managed_setup (NMDevice *self)
static void
deactivate_async_ready (NMDevice *self,
- GAsyncResult *res,
+ GError *error,
gpointer user_data)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
NMDeviceStateReason reason = GPOINTER_TO_UINT (user_data);
- GError *error = NULL;
-
- NM_DEVICE_GET_CLASS (self)->deactivate_async_finish (self, res, &error);
- /* If operation cancelled, just return */
- if ( g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)
- || (priv->deactivating_cancellable && g_cancellable_is_cancelled (priv->deactivating_cancellable))) {
- _LOGW (LOGD_DEVICE, "Deactivation cancelled");
- } else {
- /* In every other case, transition to the DISCONNECTED state */
- if (error) {
- _LOGW (LOGD_DEVICE, "Deactivation failed: %s",
- error->message);
- }
- nm_device_queue_state (self, NM_DEVICE_STATE_DISCONNECTED, reason);
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ _LOGD (LOGD_DEVICE, "Deactivation cancelled");
+ return;
}
g_clear_object (&priv->deactivating_cancellable);
- g_clear_error (&error);
+
+ /* In every other case, transition to the DISCONNECTED state */
+ if (error) {
+ _LOGW (LOGD_DEVICE, "Deactivation failed: %s",
+ error->message);
+ }
+ nm_device_queue_state (self, NM_DEVICE_STATE_DISCONNECTED, reason);
}
static void
@@ -14580,14 +14575,13 @@ deactivate_dispatcher_complete (guint call_id, gpointer user_data)
priv->dispatcher.post_state_reason = NM_DEVICE_STATE_REASON_NONE;
if (nm_clear_g_cancellable (&priv->deactivating_cancellable))
- g_warn_if_reached ();
+ nm_assert_not_reached ();
- if ( NM_DEVICE_GET_CLASS (self)->deactivate_async
- && NM_DEVICE_GET_CLASS (self)->deactivate_async_finish) {
+ if (NM_DEVICE_GET_CLASS (self)->deactivate_async) {
priv->deactivating_cancellable = g_cancellable_new ();
NM_DEVICE_GET_CLASS (self)->deactivate_async (self,
priv->deactivating_cancellable,
- (GAsyncReadyCallback) deactivate_async_ready,
+ deactivate_async_ready,
GUINT_TO_POINTER (reason));
} else
nm_device_queue_state (self, NM_DEVICE_STATE_DISCONNECTED, reason);
@@ -14644,8 +14638,8 @@ _set_state_full (NMDevice *self,
queued_state_clear (self);
dispatcher_cleanup (self);
- if (priv->deactivating_cancellable)
- g_cancellable_cancel (priv->deactivating_cancellable);
+
+ nm_clear_g_cancellable (&priv->deactivating_cancellable);
/* Cache the activation request for the dispatcher */
req = nm_g_object_ref (priv->act_request.obj);
diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h
index d1e58d4749..199ef51b0b 100644
--- a/src/devices/nm-device.h
+++ b/src/devices/nm-device.h
@@ -197,6 +197,10 @@ typedef enum { /*< skip >*/
NM_DEVICE_CHECK_DEV_AVAILABLE_ALL = (1L << 1) - 1,
} NMDeviceCheckDevAvailableFlags;
+typedef void (*NMDeviceDeactivateCallback) (NMDevice *self,
+ GError *error,
+ gpointer user_data);
+
typedef struct _NMDeviceClass {
NMDBusObjectClass parent;
@@ -354,11 +358,8 @@ typedef struct _NMDeviceClass {
/* Async deactivating (in the DEACTIVATING phase) */
void (* deactivate_async) (NMDevice *self,
GCancellable *cancellable,
- GAsyncReadyCallback callback,
+ NMDeviceDeactivateCallback callback,
gpointer user_data);
- gboolean (* deactivate_async_finish) (NMDevice *self,
- GAsyncResult *res,
- GError **error);
void (* deactivate_reset_hw_addr) (NMDevice *self);
diff --git a/src/devices/wifi/nm-device-iwd.c b/src/devices/wifi/nm-device-iwd.c
index 9038b68d14..5a601b7412 100644
--- a/src/devices/wifi/nm-device-iwd.c
+++ b/src/devices/wifi/nm-device-iwd.c
@@ -444,7 +444,10 @@ cleanup_association_attempt (NMDeviceIwd *self, gboolean disconnect)
}
static void
-reset_mode (NMDeviceIwd *self, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
+reset_mode (NMDeviceIwd *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self);
@@ -454,7 +457,9 @@ reset_mode (NMDeviceIwd *self, GCancellable *cancellable, GAsyncReadyCallback ca
"Mode",
g_variant_new_string ("station")),
G_DBUS_CALL_FLAGS_NONE, 2000,
- cancellable, callback, user_data);
+ cancellable,
+ callback,
+ user_data);
}
static void
@@ -473,43 +478,53 @@ deactivate (NMDevice *device)
reset_mode (self, NULL, NULL, NULL);
}
-static gboolean
-deactivate_async_finish (NMDevice *device, GAsyncResult *res, GError **error)
-{
- return g_task_propagate_boolean (G_TASK (res), error);
-}
-
static void
disconnect_cb (GObject *source, GAsyncResult *res, gpointer user_data)
{
- GTask *task = user_data;
+ gs_unref_object NMDeviceIwd *self = NULL;
+ NMDeviceDeactivateCallback callback;
+ gpointer callback_user_data;
gs_unref_variant GVariant *variant = NULL;
- GError *error = NULL;
+ gs_free_error GError *error = NULL;
+
+ nm_utils_user_data_unpack (user_data, &self, &callback, &callback_user_data);
variant = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), res, &error);
- if (variant)
- g_task_return_boolean (task, TRUE);
- else
- g_task_return_error (task, error);
+ callback (NM_DEVICE (self), error, callback_user_data);
+}
+
+static void
+disconnect_cb_on_idle (gpointer user_data,
+ GCancellable *cancellable)
+{
+ gs_unref_object NMDeviceIwd *self = NULL;
+ NMDeviceDeactivateCallback callback;
+ gpointer callback_user_data;
+ gs_free_error GError *cancelled_error = NULL;
- g_object_unref (task);
+ nm_utils_user_data_unpack (user_data, &self, &callback, &callback_user_data);
+
+ g_cancellable_set_error_if_cancelled (cancellable, &cancelled_error);
+ callback (NM_DEVICE (self), cancelled_error, callback_user_data);
}
static void
deactivate_async (NMDevice *device,
GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
+ NMDeviceDeactivateCallback callback,
+ gpointer callback_user_data)
{
NMDeviceIwd *self = NM_DEVICE_IWD (device);
NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self);
- GTask *task;
+ gpointer user_data;
+
+ nm_assert (G_IS_CANCELLABLE (cancellable));
+ nm_assert (callback);
- task = g_task_new (self, cancellable, callback, user_data);
+ user_data = nm_utils_user_data_pack (g_object_ref (self), callback, callback_user_data);
if (!priv->dbus_obj) {
- g_task_return_boolean (task, TRUE);
- g_object_unref (task);
+ nm_utils_invoke_on_idle (disconnect_cb_on_idle, user_data, cancellable);
return;
}
@@ -517,10 +532,16 @@ deactivate_async (NMDevice *device,
priv->act_mode_switch = FALSE;
if (priv->dbus_station_proxy) {
- g_dbus_proxy_call (priv->dbus_station_proxy, "Disconnect", g_variant_new ("()"),
- G_DBUS_CALL_FLAGS_NONE, -1, cancellable, disconnect_cb, task);
+ g_dbus_proxy_call (priv->dbus_station_proxy,
+ "Disconnect",
+ g_variant_new ("()"),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ cancellable,
+ disconnect_cb,
+ user_data);
} else
- reset_mode (self, cancellable, disconnect_cb, task);
+ reset_mode (self, cancellable, disconnect_cb, user_data);
}
static gboolean
@@ -2540,7 +2561,6 @@ nm_device_iwd_class_init (NMDeviceIwdClass *klass)
device_class->get_configured_mtu = get_configured_mtu;
device_class->deactivate = deactivate;
device_class->deactivate_async = deactivate_async;
- device_class->deactivate_async_finish = deactivate_async_finish;
device_class->can_reapply_change = can_reapply_change;
device_class->state_changed = device_state_changed;
diff --git a/src/devices/wwan/libnm-wwan.ver b/src/devices/wwan/libnm-wwan.ver
index 70b954c5d8..ea966afe6a 100644
--- a/src/devices/wwan/libnm-wwan.ver
+++ b/src/devices/wwan/libnm-wwan.ver
@@ -6,7 +6,6 @@ global:
nm_modem_complete_connection;
nm_modem_deactivate;
nm_modem_deactivate_async;
- nm_modem_deactivate_async_finish;
nm_modem_device_state_changed;
nm_modem_get_capabilities;
nm_modem_get_configured_mtu;
diff --git a/src/devices/wwan/nm-device-modem.c b/src/devices/wwan/nm-device-modem.c
index f3e2cbd7eb..e98118b60c 100644
--- a/src/devices/wwan/nm-device-modem.c
+++ b/src/devices/wwan/nm-device-modem.c
@@ -61,7 +61,7 @@ struct _NMDeviceModemClass {
G_DEFINE_TYPE (NMDeviceModem, nm_device_modem, NM_TYPE_DEVICE)
-#define NM_DEVICE_MODEM_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMDeviceModem, NM_IS_DEVICE_MODEM)
+#define NM_DEVICE_MODEM_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMDeviceModem, NM_IS_DEVICE_MODEM, NMDevice)
/*****************************************************************************/
@@ -483,44 +483,35 @@ deactivate (NMDevice *device)
/*****************************************************************************/
-static gboolean
-deactivate_async_finish (NMDevice *self,
- GAsyncResult *res,
- GError **error)
-{
- return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
-}
-
static void
-modem_deactivate_async_ready (NMModem *modem,
- GAsyncResult *res,
- GSimpleAsyncResult *simple)
+modem_deactivate_async_cb (NMModem *modem,
+ GError *error,
+ gpointer user_data)
{
- GError *error = NULL;
+ gs_unref_object NMDevice *self = NULL;
+ NMDeviceDeactivateCallback callback;
+ gpointer callback_user_data;
- if (!nm_modem_deactivate_async_finish (modem, res, &error))
- g_simple_async_result_take_error (simple, error);
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
+ nm_utils_user_data_unpack (user_data, &self, &callback, &callback_user_data);
+ callback (self, error, callback_user_data);
}
static void
deactivate_async (NMDevice *self,
GCancellable *cancellable,
- GAsyncReadyCallback callback,
+ NMDeviceDeactivateCallback callback,
gpointer user_data)
{
- GSimpleAsyncResult *simple;
+ nm_assert (G_IS_CANCELLABLE (cancellable));
+ nm_assert (callback);
- simple = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- deactivate_async);
- nm_modem_deactivate_async (NM_DEVICE_MODEM_GET_PRIVATE ((NMDeviceModem *) self)->modem,
+ nm_modem_deactivate_async (NM_DEVICE_MODEM_GET_PRIVATE (self)->modem,
self,
cancellable,
- (GAsyncReadyCallback) modem_deactivate_async_ready,
- simple);
+ modem_deactivate_async_cb,
+ nm_utils_user_data_pack (g_object_ref (self),
+ callback,
+ user_data));
}
/*****************************************************************************/
@@ -805,7 +796,6 @@ nm_device_modem_class_init (NMDeviceModemClass *klass)
device_class->check_connection_available = check_connection_available;
device_class->complete_connection = complete_connection;
device_class->deactivate_async = deactivate_async;
- device_class->deactivate_async_finish = deactivate_async_finish;
device_class->deactivate = deactivate;
device_class->act_stage1_prepare = act_stage1_prepare;
device_class->act_stage2_config = act_stage2_config;
diff --git a/src/devices/wwan/nm-modem-broadband.c b/src/devices/wwan/nm-modem-broadband.c
index 352b775829..824fd6db42 100644
--- a/src/devices/wwan/nm-modem-broadband.c
+++ b/src/devices/wwan/nm-modem-broadband.c
@@ -1098,100 +1098,101 @@ stage3_ip6_config_request (NMModem *modem, NMDeviceStateReason *out_failure_reas
typedef struct {
NMModemBroadband *self;
- GSimpleAsyncResult *result;
+ _NMModemDisconnectCallback callback;
+ gpointer callback_user_data;
GCancellable *cancellable;
gboolean warn;
} DisconnectContext;
static void
-disconnect_context_complete (DisconnectContext *ctx)
+disconnect_context_complete (DisconnectContext *ctx, GError *error)
{
- g_simple_async_result_complete_in_idle (ctx->result);
- if (ctx->cancellable)
- g_object_unref (ctx->cancellable);
- g_object_unref (ctx->result);
+ if (ctx->callback)
+ ctx->callback (NM_MODEM (ctx->self), error, ctx->callback_user_data);
+ nm_g_object_unref (ctx->cancellable);
g_object_unref (ctx->self);
g_slice_free (DisconnectContext, ctx);
}
-static gboolean
-disconnect_finish (NMModem *self,
- GAsyncResult *res,
- GError **error)
+static void
+disconnect_context_complete_on_idle (gpointer user_data,
+ GCancellable *cancellable)
{
- return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
+ DisconnectContext *ctx = NULL;
+ gs_free_error GError *cancelled_error = NULL;
+
+ g_cancellable_set_error_if_cancelled (cancellable, &cancelled_error);
+ disconnect_context_complete (ctx, cancelled_error);
}
static void
-simple_disconnect_ready (MMModemSimple *modem_iface,
+simple_disconnect_ready (GObject *source_object,
GAsyncResult *res,
- DisconnectContext *ctx)
+ gpointer user_data)
{
+ MMModemSimple *modem_iface = MM_MODEM_SIMPLE (source_object);
+ DisconnectContext *ctx = user_data;
GError *error = NULL;
if (!mm_modem_simple_disconnect_finish (modem_iface, res, &error)) {
- if (ctx->warn && !g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN)) {
+ if ( ctx->warn
+ && !g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN)) {
NMModemBroadband *self = ctx->self;
_LOGW ("failed to disconnect modem: %s",
error->message);
}
- g_simple_async_result_take_error (ctx->result, error);
}
- disconnect_context_complete (ctx);
+ disconnect_context_complete (ctx, error);
}
static void
disconnect (NMModem *modem,
gboolean warn,
GCancellable *cancellable,
- GAsyncReadyCallback callback,
+ _NMModemDisconnectCallback callback,
gpointer user_data)
{
NMModemBroadband *self = NM_MODEM_BROADBAND (modem);
DisconnectContext *ctx;
- GError *error = NULL;
connect_context_clear (self);
- ctx = g_slice_new (DisconnectContext);
- ctx->cancellable = NULL;
+
+ ctx = g_slice_new0 (DisconnectContext);
ctx->self = g_object_ref (self);
- ctx->result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- disconnect);
+ ctx->cancellable = nm_g_object_ref (cancellable);
+ ctx->callback = callback;
+ ctx->callback_user_data = user_data;
+
/* Don't bother warning on FAILED since the modem is already gone */
ctx->warn = warn;
- /* Already cancelled? */
- if (g_cancellable_set_error_if_cancelled (cancellable, &error)) {
- g_simple_async_result_take_error (ctx->result, error);
- disconnect_context_complete (ctx);
- return;
- }
-
- /* If no simple iface, we're done */
- if (!ctx->self->_priv.simple_iface) {
- disconnect_context_complete (ctx);
+ /* 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);
return;
}
_LOGD ("notifying ModemManager about the modem disconnection");
- ctx->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
- mm_modem_simple_disconnect (ctx->self->_priv.simple_iface,
+ mm_modem_simple_disconnect (self->_priv.simple_iface,
NULL, /* bearer path; if NULL given ALL get disconnected */
cancellable,
- (GAsyncReadyCallback) simple_disconnect_ready,
+ simple_disconnect_ready,
ctx);
}
/*****************************************************************************/
static void
-deactivate_cleanup (NMModem *_self, NMDevice *device)
+deactivate_cleanup (NMModem *modem,
+ NMDevice *device,
+ gboolean stop_ppp_manager)
{
- NMModemBroadband *self = NM_MODEM_BROADBAND (_self);
+ NMModemBroadband *self = NM_MODEM_BROADBAND (modem);
/* TODO: cancel SimpleConnect() if any */
@@ -1202,8 +1203,9 @@ deactivate_cleanup (NMModem *_self, NMDevice *device)
self->_priv.pin_tries = 0;
- /* Chain up parent's */
- NM_MODEM_CLASS (nm_modem_broadband_parent_class)->deactivate_cleanup (_self, device);
+ NM_MODEM_CLASS (nm_modem_broadband_parent_class)->deactivate_cleanup (modem,
+ device,
+ stop_ppp_manager);
}
/*****************************************************************************/
@@ -1468,7 +1470,6 @@ nm_modem_broadband_class_init (NMModemBroadbandClass *klass)
modem_class->static_stage3_ip4_config_start = static_stage3_ip4_config_start;
modem_class->stage3_ip6_config_request = stage3_ip6_config_request;
modem_class->disconnect = disconnect;
- modem_class->disconnect_finish = disconnect_finish;
modem_class->deactivate_cleanup = deactivate_cleanup;
modem_class->set_mm_enabled = set_mm_enabled;
modem_class->get_user_pass = get_user_pass;
diff --git a/src/devices/wwan/nm-modem-ofono.c b/src/devices/wwan/nm-modem-ofono.c
index ab5cb0befa..56b6d745c5 100644
--- a/src/devices/wwan/nm-modem-ofono.c
+++ b/src/devices/wwan/nm-modem-ofono.c
@@ -146,30 +146,36 @@ update_modem_state (NMModemOfono *self)
/* Disconnect */
typedef struct {
NMModemOfono *self;
- GSimpleAsyncResult *result;
+ _NMModemDisconnectCallback callback;
+ gpointer callback_user_data;
GCancellable *cancellable;
gboolean warn;
} DisconnectContext;
static void
-disconnect_context_complete (DisconnectContext *ctx)
+disconnect_context_complete (DisconnectContext *ctx, GError *error)
{
- if (ctx->cancellable)
- g_object_unref (ctx->cancellable);
- if (ctx->result) {
- g_simple_async_result_complete_in_idle (ctx->result);
- g_object_unref (ctx->result);
- }
+ if (ctx->callback)
+ ctx->callback (NM_MODEM (ctx->self), error, ctx->callback_user_data);
+ nm_g_object_unref (ctx->cancellable);
g_object_unref (ctx->self);
g_slice_free (DisconnectContext, ctx);
}
-static gboolean
-disconnect_finish (NMModem *self,
- GAsyncResult *result,
- GError **error)
+static void
+disconnect_context_complete_on_idle (gpointer user_data,
+ GCancellable *cancellable)
{
- return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error);
+ DisconnectContext *ctx = NULL;
+ gs_free_error GError *error = NULL;
+
+ if (!g_cancellable_set_error_if_cancelled (cancellable, &error)) {
+ g_set_error_literal (&error,
+ NM_UTILS_ERROR,
+ NM_UTILS_ERROR_UNKNOWN,
+ ("modem is currently not connected"));
+ }
+ disconnect_context_complete (ctx, error);
}
static void
@@ -177,16 +183,14 @@ disconnect_done (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
- DisconnectContext *ctx = (DisconnectContext*) user_data;
+ DisconnectContext *ctx = user_data;
NMModemOfono *self = ctx->self;
gs_free_error GError *error = NULL;
gs_unref_variant GVariant *v = NULL;
v = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), result, &error);
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
- if (ctx->result)
- g_simple_async_result_take_error (ctx->result, g_steal_pointer (&error));
- disconnect_context_complete (ctx);
+ disconnect_context_complete (ctx, error);
return;
}
@@ -196,21 +200,21 @@ disconnect_done (GObject *source,
_LOGD ("modem disconnected");
update_modem_state (self);
- disconnect_context_complete (ctx);
+ disconnect_context_complete (ctx, error);
}
static void
disconnect (NMModem *modem,
gboolean warn,
GCancellable *cancellable,
- GAsyncReadyCallback callback,
+ _NMModemDisconnectCallback callback,
gpointer user_data)
{
NMModemOfono *self = NM_MODEM_OFONO (modem);
NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
DisconnectContext *ctx;
NMModemState state = nm_modem_get_state (NM_MODEM (self));
- GError *error = NULL;
+ gs_free_error GError *error = NULL;
_LOGD ("warn: %s modem_state: %s",
warn ? "TRUE" : "FALSE",
@@ -218,37 +222,19 @@ disconnect (NMModem *modem,
ctx = g_slice_new0 (DisconnectContext);
ctx->self = g_object_ref (self);
+ ctx->cancellable = nm_g_object_ref (cancellable);
ctx->warn = warn;
- if (callback) {
- ctx->result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- disconnect);
- }
-
- if (state != NM_MODEM_STATE_CONNECTED) {
- if (ctx->result) {
- g_set_error_literal (&error,
- NM_UTILS_ERROR,
- NM_UTILS_ERROR_UNKNOWN,
- ("modem is currently not connected"));
- g_simple_async_result_take_error (ctx->result, error);
- }
- disconnect_context_complete (ctx);
+ ctx->callback = callback;
+ ctx->callback_user_data = user_data;
+
+ if ( state != NM_MODEM_STATE_CONNECTED
+ || g_cancellable_is_cancelled (cancellable)) {
+ nm_utils_invoke_on_idle (disconnect_context_complete_on_idle,
+ ctx,
+ cancellable);
return;
}
- if (g_cancellable_set_error_if_cancelled (cancellable, &error)) {
- if (ctx->result)
- g_simple_async_result_take_error (ctx->result, error);
- else
- g_clear_error (&error);
- disconnect_context_complete (ctx);
- return;
- }
-
- ctx->cancellable = nm_g_object_ref (cancellable);
-
nm_modem_set_state (NM_MODEM (self),
NM_MODEM_STATE_DISCONNECTING,
nm_modem_state_to_string (NM_MODEM_STATE_DISCONNECTING));
@@ -266,7 +252,9 @@ disconnect (NMModem *modem,
}
static void
-deactivate_cleanup (NMModem *modem, NMDevice *device)
+deactivate_cleanup (NMModem *modem,
+ NMDevice *device,
+ gboolean stop_ppp_manager)
{
NMModemOfono *self = NM_MODEM_OFONO (modem);
NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
@@ -275,7 +263,9 @@ deactivate_cleanup (NMModem *modem, NMDevice *device)
g_clear_object (&priv->ip4_config);
- NM_MODEM_CLASS (nm_modem_ofono_parent_class)->deactivate_cleanup (modem, device);
+ NM_MODEM_CLASS (nm_modem_ofono_parent_class)->deactivate_cleanup (modem,
+ device,
+ stop_ppp_manager);
}
static gboolean
@@ -1319,7 +1309,6 @@ nm_modem_ofono_class_init (NMModemOfonoClass *klass)
modem_class->get_capabilities = get_capabilities;
modem_class->disconnect = disconnect;
- modem_class->disconnect_finish = disconnect_finish;
modem_class->deactivate_cleanup = deactivate_cleanup;
modem_class->check_connection_compatible_with_modem = check_connection_compatible_with_modem;
diff --git a/src/devices/wwan/nm-modem.c b/src/devices/wwan/nm-modem.c
index 59b081e980..56d9811645 100644
--- a/src/devices/wwan/nm-modem.c
+++ b/src/devices/wwan/nm-modem.c
@@ -1105,7 +1105,9 @@ nm_modem_complete_connection (NMModem *self,
/*****************************************************************************/
static void
-deactivate_cleanup (NMModem *self, NMDevice *device)
+deactivate_cleanup (NMModem *self,
+ NMDevice *device,
+ gboolean stop_ppp_manager)
{
NMModemPrivate *priv;
int ifindex;
@@ -1126,7 +1128,8 @@ deactivate_cleanup (NMModem *self, NMDevice *device)
if (priv->ppp_manager) {
g_signal_handlers_disconnect_by_data (priv->ppp_manager, self);
- nm_ppp_manager_stop (priv->ppp_manager, NULL, NULL);
+ if (stop_ppp_manager)
+ nm_ppp_manager_stop (priv->ppp_manager, NULL, NULL, NULL);
g_clear_object (&priv->ppp_manager);
}
@@ -1157,189 +1160,109 @@ deactivate_cleanup (NMModem *self, NMDevice *device)
/*****************************************************************************/
-typedef enum {
- DEACTIVATE_CONTEXT_STEP_FIRST,
- DEACTIVATE_CONTEXT_STEP_CLEANUP,
- DEACTIVATE_CONTEXT_STEP_PPP_MANAGER_STOP,
- DEACTIVATE_CONTEXT_STEP_MM_DISCONNECT,
- DEACTIVATE_CONTEXT_STEP_LAST
-} DeactivateContextStep;
-
typedef struct {
NMModem *self;
NMDevice *device;
GCancellable *cancellable;
- GSimpleAsyncResult *result;
- DeactivateContextStep step;
- NMPPPManager *ppp_manager;
- NMPPPManagerStopHandle *ppp_stop_handle;
- gulong ppp_stop_cancellable_id;
+ NMModemDeactivateCallback callback;
+ gpointer callback_user_data;
} DeactivateContext;
static void
-deactivate_context_complete (DeactivateContext *ctx)
+deactivate_context_complete (DeactivateContext *ctx, GError *error)
{
- if (ctx->ppp_stop_handle)
- nm_ppp_manager_stop_cancel (ctx->ppp_stop_handle);
+ NMModem *self = ctx->self;
- nm_assert (!ctx->ppp_stop_handle);
- nm_assert (ctx->ppp_stop_cancellable_id == 0);
+ _LOGD ("modem deactivation finished %s%s%s",
+ NM_PRINT_FMT_QUOTED (error, "with failure: ", error->message, "", "successfully"));
- if (ctx->ppp_manager)
- g_object_unref (ctx->ppp_manager);
- if (ctx->cancellable)
- g_object_unref (ctx->cancellable);
- g_simple_async_result_complete_in_idle (ctx->result);
- g_object_unref (ctx->result);
+ if (ctx->callback)
+ ctx->callback (ctx->self, error, ctx->callback_user_data);
+ nm_g_object_unref (ctx->cancellable);
g_object_unref (ctx->device);
g_object_unref (ctx->self);
g_slice_free (DeactivateContext, ctx);
}
-gboolean
-nm_modem_deactivate_async_finish (NMModem *self,
- GAsyncResult *res,
- GError **error)
-{
- return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
-}
-
-static void deactivate_step (DeactivateContext *ctx);
-
static void
-disconnect_ready (NMModem *self,
- GAsyncResult *res,
- DeactivateContext *ctx)
+_deactivate_call_disconnect_cb (NMModem *self,
+ GError *error,
+ gpointer user_data)
{
- GError *error = NULL;
-
- if (!NM_MODEM_GET_CLASS (self)->disconnect_finish (self, res, &error)) {
- g_simple_async_result_take_error (ctx->result, error);
- deactivate_context_complete (ctx);
- return;
- }
-
- /* Go on */
- ctx->step++;
- deactivate_step (ctx);
+ deactivate_context_complete (user_data, error);
}
static void
-ppp_manager_stop_ready (NMPPPManager *ppp_manager,
- NMPPPManagerStopHandle *handle,
- gboolean was_cancelled,
- gpointer user_data)
+_deactivate_call_disconnect (DeactivateContext *ctx)
{
- DeactivateContext *ctx = user_data;
-
- nm_assert (ctx->ppp_stop_handle == handle);
- ctx->ppp_stop_handle = NULL;
-
- if (ctx->ppp_stop_cancellable_id) {
- g_cancellable_disconnect (ctx->cancellable,
- nm_steal_int (&ctx->ppp_stop_cancellable_id));
- }
-
- if (was_cancelled)
- return;
-
- ctx->step++;
- deactivate_step (ctx);
+ NM_MODEM_GET_CLASS (ctx->self)->disconnect (ctx->self,
+ FALSE,
+ ctx->cancellable,
+ _deactivate_call_disconnect_cb,
+ ctx);
}
static void
-ppp_manager_stop_cancelled (GCancellable *cancellable,
- gpointer user_data)
+_deactivate_ppp_manager_stop_cb (NMPPPManager *ppp_manager,
+ NMPPPManagerStopHandle *handle,
+ gboolean was_cancelled,
+ gpointer user_data)
{
DeactivateContext *ctx = user_data;
- nm_ppp_manager_stop_cancel (ctx->ppp_stop_handle);
-}
-
-static void
-deactivate_step (DeactivateContext *ctx)
-{
- NMModem *self = ctx->self;
- NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self);
- GError *error = NULL;
+ g_object_unref (ppp_manager);
- /* Check cancellable in each step */
- if (g_cancellable_set_error_if_cancelled (ctx->cancellable, &error)) {
- g_simple_async_result_take_error (ctx->result, error);
- deactivate_context_complete (ctx);
- return;
- }
-
- switch (ctx->step) {
- case DEACTIVATE_CONTEXT_STEP_FIRST:
- ctx->step++;
- /* fall through */
- case DEACTIVATE_CONTEXT_STEP_CLEANUP:
- /* Make sure we keep a ref to the PPP manager if there is one */
- if (priv->ppp_manager)
- ctx->ppp_manager = g_object_ref (priv->ppp_manager);
- /* Run cleanup */
- NM_MODEM_GET_CLASS (self)->deactivate_cleanup (self, ctx->device);
- ctx->step++;
- /* fall through */
- case DEACTIVATE_CONTEXT_STEP_PPP_MANAGER_STOP:
- /* If we have a PPP manager, stop it */
- if (ctx->ppp_manager) {
- nm_assert (!ctx->ppp_stop_handle);
- if (ctx->cancellable) {
- ctx->ppp_stop_cancellable_id = g_cancellable_connect (ctx->cancellable,
- G_CALLBACK (ppp_manager_stop_cancelled),
- ctx,
- NULL);
- }
- ctx->ppp_stop_handle = nm_ppp_manager_stop (ctx->ppp_manager,
- ppp_manager_stop_ready,
- ctx);
- return;
- }
- ctx->step++;
- /* fall through */
- case DEACTIVATE_CONTEXT_STEP_MM_DISCONNECT:
- /* Disconnect asynchronously */
- NM_MODEM_GET_CLASS (self)->disconnect (self,
- FALSE,
- ctx->cancellable,
- (GAsyncReadyCallback) disconnect_ready,
- ctx);
- return;
+ if (was_cancelled) {
+ gs_free_error GError *error = NULL;
- case DEACTIVATE_CONTEXT_STEP_LAST:
- _LOGD ("modem deactivation finished");
- deactivate_context_complete (ctx);
+ if (!g_cancellable_set_error_if_cancelled (ctx->cancellable, &error))
+ nm_assert_not_reached ();
+ deactivate_context_complete (ctx, error);
return;
}
- g_assert_not_reached ();
+ nm_assert (!g_cancellable_is_cancelled (ctx->cancellable));
+ _deactivate_call_disconnect (ctx);
}
void
nm_modem_deactivate_async (NMModem *self,
NMDevice *device,
GCancellable *cancellable,
- GAsyncReadyCallback callback,
+ NMModemDeactivateCallback callback,
gpointer user_data)
{
+ NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self);
DeactivateContext *ctx;
+ NMPPPManager *ppp_manager;
+
+ g_return_if_fail (NM_IS_MODEM (self));
+ g_return_if_fail (NM_IS_DEVICE (device));
+ g_return_if_fail (G_IS_CANCELLABLE (cancellable));
- ctx = g_slice_new0 (DeactivateContext);
+ ctx = g_slice_new (DeactivateContext);
ctx->self = g_object_ref (self);
ctx->device = g_object_ref (device);
- ctx->result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- nm_modem_deactivate_async);
- /* FIXME(shutdown): we always require a cancellable, otherwise we cannot
- * do a coordinated shutdown. */
- ctx->cancellable = nm_g_object_ref (cancellable);
+ ctx->cancellable = g_object_ref (cancellable);
+ ctx->callback = callback;
+ ctx->callback_user_data = user_data;
+
+ ppp_manager = nm_g_object_ref (priv->ppp_manager);
+
+ NM_MODEM_GET_CLASS (self)->deactivate_cleanup (self, ctx->device, FALSE);
+
+ if (ppp_manager) {
+ /* If we have a PPP manager, stop it.
+ *
+ * Pass on the reference in @ppp_manager. */
+ nm_ppp_manager_stop (ppp_manager,
+ ctx->cancellable,
+ _deactivate_ppp_manager_stop_cb,
+ ctx);
+ return;
+ }
- /* Start */
- ctx->step = DEACTIVATE_CONTEXT_STEP_FIRST;
- deactivate_step (ctx);
+ _deactivate_call_disconnect (ctx);
}
/*****************************************************************************/
@@ -1348,7 +1271,7 @@ void
nm_modem_deactivate (NMModem *self, NMDevice *device)
{
/* First cleanup */
- NM_MODEM_GET_CLASS (self)->deactivate_cleanup (self, device);
+ NM_MODEM_GET_CLASS (self)->deactivate_cleanup (self, device, TRUE);
/* Then disconnect without waiting */
NM_MODEM_GET_CLASS (self)->disconnect (self, FALSE, NULL, NULL, NULL);
}
@@ -1387,7 +1310,7 @@ nm_modem_device_state_changed (NMModem *self,
if (new_state == NM_DEVICE_STATE_FAILED || new_state == NM_DEVICE_STATE_DISCONNECTED)
warn = FALSE;
/* First cleanup */
- NM_MODEM_GET_CLASS (self)->deactivate_cleanup (self, NULL);
+ NM_MODEM_GET_CLASS (self)->deactivate_cleanup (self, NULL, TRUE);
NM_MODEM_GET_CLASS (self)->disconnect (self, warn, NULL, NULL, NULL);
}
break;
diff --git a/src/devices/wwan/nm-modem.h b/src/devices/wwan/nm-modem.h
index c73745cef3..f7b6bfe959 100644
--- a/src/devices/wwan/nm-modem.h
+++ b/src/devices/wwan/nm-modem.h
@@ -109,6 +109,10 @@ struct _NMModem {
typedef struct _NMModem NMModem;
+typedef void (*_NMModemDisconnectCallback) (NMModem *modem,
+ GError *error,
+ gpointer user_data);
+
typedef struct {
GObjectClass parent;
@@ -149,13 +153,12 @@ typedef struct {
void (*disconnect) (NMModem *self,
gboolean warn,
GCancellable *cancellable,
- GAsyncReadyCallback callback,
+ _NMModemDisconnectCallback callback,
gpointer user_data);
- gboolean (*disconnect_finish) (NMModem *self,
- GAsyncResult *res,
- GError **error);
- void (*deactivate_cleanup) (NMModem *self, NMDevice *device);
+ void (*deactivate_cleanup) (NMModem *self,
+ NMDevice *device,
+ gboolean stop_ppp_manager);
gboolean (*owns_port) (NMModem *self, const char *iface);
} NMModemClass;
@@ -236,14 +239,15 @@ void nm_modem_get_secrets (NMModem *modem,
void nm_modem_deactivate (NMModem *modem, NMDevice *device);
+typedef void (*NMModemDeactivateCallback) (NMModem *self,
+ GError *error,
+ gpointer user_data);
+
void nm_modem_deactivate_async (NMModem *self,
NMDevice *device,
GCancellable *cancellable,
- GAsyncReadyCallback callback,
+ NMModemDeactivateCallback callback,
gpointer user_data);
-gboolean nm_modem_deactivate_async_finish (NMModem *self,
- GAsyncResult *res,
- GError **error);
void nm_modem_device_state_changed (NMModem *modem,
NMDeviceState new_state,
diff --git a/src/ppp/nm-ppp-manager-call.c b/src/ppp/nm-ppp-manager-call.c
index 3d6fee49a0..8f6584167a 100644
--- a/src/ppp/nm-ppp-manager-call.c
+++ b/src/ppp/nm-ppp-manager-call.c
@@ -126,12 +126,13 @@ nm_ppp_manager_start (NMPPPManager *self,
NMPPPManagerStopHandle *
nm_ppp_manager_stop (NMPPPManager *self,
+ GCancellable *cancellable,
NMPPPManagerStopCallback callback,
gpointer user_data)
{
g_return_val_if_fail (ppp_ops, NULL);
- return ppp_ops->stop (self, callback, user_data);
+ return ppp_ops->stop (self, cancellable, callback, user_data);
}
void
diff --git a/src/ppp/nm-ppp-manager-call.h b/src/ppp/nm-ppp-manager-call.h
index daf8a82e68..a93ed11fc0 100644
--- a/src/ppp/nm-ppp-manager-call.h
+++ b/src/ppp/nm-ppp-manager-call.h
@@ -40,6 +40,7 @@ gboolean nm_ppp_manager_start (NMPPPManager *self,
GError **error);
NMPPPManagerStopHandle *nm_ppp_manager_stop (NMPPPManager *self,
+ GCancellable *cancellable,
NMPPPManagerStopCallback callback,
gpointer user_data);
diff --git a/src/ppp/nm-ppp-manager.c b/src/ppp/nm-ppp-manager.c
index b231ff2059..1595961f45 100644
--- a/src/ppp/nm-ppp-manager.c
+++ b/src/ppp/nm-ppp-manager.c
@@ -137,9 +137,12 @@ G_DEFINE_TYPE (NMPPPManager, nm_ppp_manager, NM_TYPE_DBUS_OBJECT)
static void _ppp_cleanup (NMPPPManager *self);
static NMPPPManagerStopHandle *_ppp_manager_stop (NMPPPManager *self,
+ GCancellable *cancellable,
NMPPPManagerStopCallback callback,
gpointer user_data);
+static void _ppp_manager_stop_cancel (NMPPPManagerStopHandle *handle);
+
/*****************************************************************************/
static void
@@ -791,7 +794,7 @@ pppd_timed_out (gpointer data)
NMPPPManager *self = NM_PPP_MANAGER (data);
_LOGW ("pppd timed out or didn't initialize our dbus module");
- _ppp_manager_stop (self, NULL, NULL);
+ _ppp_manager_stop (self, NULL, NULL, NULL);
g_signal_emit (self, signals[STATE_CHANGED], 0, (guint) NM_PPP_STATUS_DEAD);
@@ -1170,6 +1173,10 @@ struct _NMPPPManagerStopHandle {
* pppd process terminated. */
GObject *shutdown_waitobj;
+ GCancellable *cancellable;
+
+ gulong cancellable_id;
+
guint idle_id;
};
@@ -1179,6 +1186,13 @@ _stop_handle_complete (NMPPPManagerStopHandle *handle, gboolean was_cancelled)
gs_unref_object NMPPPManager *self = NULL;
NMPPPManagerStopCallback callback;
+ if (handle->cancellable_id) {
+ g_cancellable_disconnect (handle->cancellable,
+ nm_steal_int (&handle->cancellable_id));
+ }
+
+ g_clear_object (&handle->cancellable);
+
self = g_steal_pointer (&handle->self);
if (!self)
return;
@@ -1219,8 +1233,20 @@ _stop_idle_cb (gpointer user_data)
return G_SOURCE_REMOVE;
}
+static void
+_stop_cancelled_cb (GCancellable *cancellable,
+ gpointer user_data)
+{
+ NMPPPManagerStopHandle *handle = user_data;
+
+ nm_clear_g_signal_handler (handle->cancellable,
+ &handle->cancellable_id);
+ _ppp_manager_stop_cancel (handle);
+}
+
static NMPPPManagerStopHandle *
_ppp_manager_stop (NMPPPManager *self,
+ GCancellable *cancellable,
NMPPPManagerStopCallback callback,
gpointer user_data)
{
@@ -1246,6 +1272,13 @@ _ppp_manager_stop (NMPPPManager *self,
handle->self = g_object_ref (self);
handle->callback = callback;
handle->user_data = user_data;
+ if (cancellable) {
+ handle->cancellable = g_object_ref (cancellable);
+ handle->cancellable_id = g_cancellable_connect (cancellable,
+ G_CALLBACK (_stop_cancelled_cb),
+ handle,
+ NULL);
+ }
if (!priv->pid) {
/* No PID. There is nothing to kill, however, invoke the callback in
@@ -1272,6 +1305,8 @@ _ppp_manager_stop (NMPPPManager *self,
return handle;
}
+/*****************************************************************************/
+
static void
_ppp_manager_stop_cancel (NMPPPManagerStopHandle *handle)
{
@@ -1360,7 +1395,7 @@ dispose (GObject *object)
* still stop. */
g_warn_if_fail (!priv->pid);
g_warn_if_fail (!nm_dbus_object_is_exported (NM_DBUS_OBJECT (self)));
- _ppp_manager_stop (self, NULL, NULL);
+ _ppp_manager_stop (self, NULL, NULL, NULL);
g_clear_object (&priv->act_req);
diff --git a/src/ppp/nm-ppp-plugin-api.h b/src/ppp/nm-ppp-plugin-api.h
index 558de2c2c2..95ddd21191 100644
--- a/src/ppp/nm-ppp-plugin-api.h
+++ b/src/ppp/nm-ppp-plugin-api.h
@@ -40,6 +40,7 @@ typedef const struct {
GError **err);
NMPPPManagerStopHandle *(*stop) (NMPPPManager *manager,
+ GCancellable *cancellable,
NMPPPManagerStopCallback callback,
gpointer user_data);