aboutsummaryrefslogtreecommitdiff
path: root/src/mm-bearer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mm-bearer.c')
-rw-r--r--src/mm-bearer.c103
1 files changed, 80 insertions, 23 deletions
diff --git a/src/mm-bearer.c b/src/mm-bearer.c
index 5aa713e2..921ff702 100644
--- a/src/mm-bearer.c
+++ b/src/mm-bearer.c
@@ -13,6 +13,7 @@
* Copyright (C) 2008 - 2009 Novell, Inc.
* Copyright (C) 2009 - 2011 Red Hat, Inc.
* Copyright (C) 2011 Google, Inc.
+ * Copyright (C) 2011 - 2013 Aleksander Morgado <aleksander@gnu.org>
*/
#include <config.h>
@@ -373,17 +374,11 @@ connect_ready (MMBearer *self,
{
GError *error = NULL;
gboolean launch_disconnect = FALSE;
- MMPort *data = NULL;
- MMBearerIpConfig *ipv4_config = NULL;
- MMBearerIpConfig *ipv6_config = NULL;
+ MMBearerConnectResult *result;
/* NOTE: connect() implementations *MUST* handle cancellations themselves */
- if (!MM_BEARER_GET_CLASS (self)->connect_finish (self,
- res,
- &data,
- &ipv4_config,
- &ipv6_config,
- &error)) {
+ result = MM_BEARER_GET_CLASS (self)->connect_finish (self, res, &error);
+ if (!result) {
mm_dbg ("Couldn't connect bearer '%s': '%s'",
self->priv->path,
error->message);
@@ -400,11 +395,7 @@ connect_ready (MMBearer *self,
/* Handle cancellations detected after successful connection */
else if (g_cancellable_is_cancelled (self->priv->connect_cancellable)) {
mm_dbg ("Connected bearer '%s', but need to disconnect", self->priv->path);
-
- g_clear_object (&data);
- g_clear_object (&ipv4_config);
- g_clear_object (&ipv6_config);
-
+ mm_bearer_connect_result_unref (result);
g_simple_async_result_set_error (
simple,
MM_CORE_ERROR,
@@ -416,15 +407,12 @@ connect_ready (MMBearer *self,
mm_dbg ("Connected bearer '%s'", self->priv->path);
/* Update bearer and interface status */
- bearer_update_status_connected (self,
- mm_port_get_device (data),
- ipv4_config,
- ipv6_config);
-
- g_clear_object (&data);
- g_clear_object (&ipv4_config);
- g_clear_object (&ipv6_config);
-
+ bearer_update_status_connected (
+ self,
+ mm_port_get_device (mm_bearer_connect_result_peek_data (result)),
+ mm_bearer_connect_result_peek_ipv4_config (result),
+ mm_bearer_connect_result_peek_ipv6_config (result));
+ mm_bearer_connect_result_unref (result);
g_simple_async_result_set_op_res_gboolean (simple, TRUE);
}
@@ -1123,3 +1111,72 @@ mm_bearer_class_init (MMBearerClass *klass)
G_PARAM_READWRITE);
g_object_class_install_property (object_class, PROP_CONFIG, properties[PROP_CONFIG]);
}
+
+/*****************************************************************************/
+/* Helpers to implement connect() */
+
+struct _MMBearerConnectResult {
+ volatile gint ref_count;
+ MMPort *data;
+ MMBearerIpConfig *ipv4_config;
+ MMBearerIpConfig *ipv6_config;
+};
+
+MMBearerConnectResult *
+mm_bearer_connect_result_ref (MMBearerConnectResult *result)
+{
+ g_atomic_int_inc (&result->ref_count);
+ return result;
+}
+
+void
+mm_bearer_connect_result_unref (MMBearerConnectResult *result)
+{
+ if (g_atomic_int_dec_and_test (&result->ref_count)) {
+ if (result->ipv4_config)
+ g_object_unref (result->ipv4_config);
+ if (result->ipv6_config)
+ g_object_unref (result->ipv6_config);
+ if (result->data)
+ g_object_unref (result->data);
+ g_slice_free (MMBearerConnectResult, result);
+ }
+}
+
+MMPort *
+mm_bearer_connect_result_peek_data (MMBearerConnectResult *result)
+{
+ return result->data;
+}
+
+MMBearerIpConfig *
+mm_bearer_connect_result_peek_ipv4_config (MMBearerConnectResult *result)
+{
+ return result->ipv4_config;
+}
+
+MMBearerIpConfig *
+mm_bearer_connect_result_peek_ipv6_config (MMBearerConnectResult *result)
+{
+ return result->ipv6_config;
+}
+
+MMBearerConnectResult *
+mm_bearer_connect_result_new (MMPort *data,
+ MMBearerIpConfig *ipv4_config,
+ MMBearerIpConfig *ipv6_config)
+{
+ MMBearerConnectResult *result;
+
+ /* 'data' must always be given */
+ g_assert (MM_IS_PORT (data));
+
+ result = g_slice_new0 (MMBearerConnectResult);
+ result->ref_count = 1;
+ result->data = g_object_ref (data);
+ if (ipv4_config)
+ result->ipv4_config = g_object_ref (ipv4_config);
+ if (ipv6_config)
+ result->ipv6_config = g_object_ref (ipv6_config);
+ return result;
+}