base-modem: new modem-wide cancellable, passed to every state machine

This commit is contained in:
Aleksander Morgado
2012-03-08 15:30:48 +01:00
parent 7bfc56c2a8
commit 215c278082
3 changed files with 155 additions and 53 deletions

View File

@@ -55,6 +55,10 @@ struct _MMBaseModemPrivate {
/* The connection to the system bus */ /* The connection to the system bus */
GDBusConnection *connection; GDBusConnection *connection;
/* Modem-wide cancellable. If it ever gets cancelled, no further operations
* should be done by the modem. */
GCancellable *cancellable;
gchar *device; gchar *device;
gchar *driver; gchar *driver;
gchar *plugin; gchar *plugin;
@@ -65,7 +69,6 @@ struct _MMBaseModemPrivate {
gboolean valid; gboolean valid;
guint max_timeouts; guint max_timeouts;
guint set_invalid_unresponsive_modem_id;
/* The authorization provider */ /* The authorization provider */
MMAuthProvider *authp; MMAuthProvider *authp;
@@ -117,14 +120,6 @@ mm_base_modem_owns_port (MMBaseModem *self,
return !!mm_base_modem_get_port (self, subsys, name); return !!mm_base_modem_get_port (self, subsys, name);
} }
static gboolean
set_invalid_unresponsive_modem_cb (MMBaseModem *self)
{
mm_base_modem_set_valid (self, FALSE);
self->priv->set_invalid_unresponsive_modem_id = 0;
return FALSE;
}
static void static void
serial_port_timed_out_cb (MMSerialPort *port, serial_port_timed_out_cb (MMSerialPort *port,
guint n_consecutive_timeouts, guint n_consecutive_timeouts,
@@ -141,9 +136,7 @@ serial_port_timed_out_cb (MMSerialPort *port,
g_dbus_object_get_object_path (G_DBUS_OBJECT (self))); g_dbus_object_get_object_path (G_DBUS_OBJECT (self)));
/* Only set action to invalidate modem if not already done */ /* Only set action to invalidate modem if not already done */
if (!self->priv->set_invalid_unresponsive_modem_id) g_cancellable_cancel (self->priv->cancellable);
self->priv->set_invalid_unresponsive_modem_id =
g_idle_add ((GSourceFunc)set_invalid_unresponsive_modem_cb, self);
} }
} }
@@ -275,8 +268,13 @@ mm_base_modem_release_port (MMBaseModem *self,
return; return;
} }
if (port == (MMPort *)self->priv->primary) if (port == (MMPort *)self->priv->primary) {
/* Cancel modem-wide cancellable; no further actions can be done
* without a primary port. */
g_cancellable_cancel (self->priv->cancellable);
g_clear_object (&self->priv->primary); g_clear_object (&self->priv->primary);
}
if (port == (MMPort *)self->priv->data) if (port == (MMPort *)self->priv->data)
g_clear_object (&self->priv->data); g_clear_object (&self->priv->data);
@@ -297,6 +295,75 @@ mm_base_modem_release_port (MMBaseModem *self,
g_free (key); g_free (key);
} }
gboolean
mm_base_modem_disable_finish (MMBaseModem *self,
GAsyncResult *res,
GError **error)
{
return MM_BASE_MODEM_GET_CLASS (self)->disable_finish (self, res, error);
}
void
mm_base_modem_disable (MMBaseModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
g_assert (MM_BASE_MODEM_GET_CLASS (self)->disable != NULL);
g_assert (MM_BASE_MODEM_GET_CLASS (self)->disable_finish != NULL);
MM_BASE_MODEM_GET_CLASS (self)->disable (
self,
self->priv->cancellable,
callback,
user_data);
}
gboolean
mm_base_modem_enable_finish (MMBaseModem *self,
GAsyncResult *res,
GError **error)
{
return MM_BASE_MODEM_GET_CLASS (self)->enable_finish (self, res, error);
}
void
mm_base_modem_enable (MMBaseModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
g_assert (MM_BASE_MODEM_GET_CLASS (self)->enable != NULL);
g_assert (MM_BASE_MODEM_GET_CLASS (self)->enable_finish != NULL);
MM_BASE_MODEM_GET_CLASS (self)->enable (
self,
self->priv->cancellable,
callback,
user_data);
}
gboolean
mm_base_modem_initialize_finish (MMBaseModem *self,
GAsyncResult *res,
GError **error)
{
return MM_BASE_MODEM_GET_CLASS (self)->initialize_finish (self, res, error);
}
void
mm_base_modem_initialize (MMBaseModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
g_assert (MM_BASE_MODEM_GET_CLASS (self)->initialize != NULL);
g_assert (MM_BASE_MODEM_GET_CLASS (self)->initialize_finish != NULL);
MM_BASE_MODEM_GET_CLASS (self)->initialize (
self,
self->priv->cancellable,
callback,
user_data);
}
void void
mm_base_modem_set_valid (MMBaseModem *self, mm_base_modem_set_valid (MMBaseModem *self,
gboolean new_valid) gboolean new_valid)
@@ -429,7 +496,7 @@ initialize_ready (MMBaseModem *self,
{ {
GError *error = NULL; GError *error = NULL;
if (!MM_BASE_MODEM_GET_CLASS (self)->initialize_finish (self, res, &error)) { if (!mm_base_modem_initialize_finish (self, res, &error)) {
/* Wrong state is returned when modem is found locked */ /* Wrong state is returned when modem is found locked */
if (g_error_matches (error, if (g_error_matches (error,
MM_CORE_ERROR, MM_CORE_ERROR,
@@ -579,10 +646,9 @@ mm_base_modem_organize_ports (MMBaseModem *self,
self->priv->qcdm = (qcdm ? g_object_ref (qcdm) : NULL); self->priv->qcdm = (qcdm ? g_object_ref (qcdm) : NULL);
/* As soon as we get the ports organized, we initialize the modem */ /* As soon as we get the ports organized, we initialize the modem */
MM_BASE_MODEM_GET_CLASS (self)->initialize (self, mm_base_modem_initialize (self,
NULL, /* TODO: cancellable */ (GAsyncReadyCallback)initialize_ready,
(GAsyncReadyCallback)initialize_ready, NULL);
NULL);
return TRUE; return TRUE;
} }
@@ -679,6 +745,27 @@ mm_base_modem_get_product_id (MMBaseModem *self)
/*****************************************************************************/ /*****************************************************************************/
static gboolean
base_modem_invalid_idle (MMBaseModem *self)
{
/* Ensure the modem is set invalid if we get the modem-wide cancellable
* cancelled */
mm_base_modem_set_valid (self, FALSE);
g_object_unref (self);
return FALSE;
}
static void
base_modem_cancelled (GCancellable *cancellable,
MMBaseModem *self)
{
/* NOTE: Don't call set_valid() directly here, do it in an idle, and ensure
* that we pass a valid reference of the modem object as context. */
g_idle_add ((GSourceFunc)base_modem_invalid_idle, g_object_ref (self));
}
/*****************************************************************************/
static void static void
mm_base_modem_init (MMBaseModem *self) mm_base_modem_init (MMBaseModem *self)
{ {
@@ -691,6 +778,13 @@ mm_base_modem_init (MMBaseModem *self)
self->priv->authp = mm_auth_get_provider (); self->priv->authp = mm_auth_get_provider ();
self->priv->authp_cancellable = g_cancellable_new (); self->priv->authp_cancellable = g_cancellable_new ();
/* Setup modem-wide cancellable */
self->priv->cancellable = g_cancellable_new ();
g_cancellable_connect (self->priv->cancellable,
G_CALLBACK (base_modem_cancelled),
self,
NULL);
self->priv->ports = g_hash_table_new_full (g_str_hash, self->priv->ports = g_hash_table_new_full (g_str_hash,
g_str_equal, g_str_equal,
g_free, g_free,
@@ -817,6 +911,8 @@ dispose (GObject *object)
self->priv->ports = NULL; self->priv->ports = NULL;
} }
g_clear_object (&self->priv->cancellable);
g_clear_object (&self->priv->connection); g_clear_object (&self->priv->connection);
g_clear_object (&self->priv->authp); g_clear_object (&self->priv->authp);

View File

@@ -133,15 +133,6 @@ void mm_base_modem_set_valid (MMBaseModem *self,
gboolean valid); gboolean valid);
gboolean mm_base_modem_get_valid (MMBaseModem *self); gboolean mm_base_modem_get_valid (MMBaseModem *self);
void mm_base_modem_authorize (MMBaseModem *self,
GDBusMethodInvocation *invocation,
const gchar *authorization,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean mm_base_modem_authorize_finish (MMBaseModem *self,
GAsyncResult *res,
GError **error);
const gchar *mm_base_modem_get_device (MMBaseModem *self); const gchar *mm_base_modem_get_device (MMBaseModem *self);
const gchar *mm_base_modem_get_driver (MMBaseModem *self); const gchar *mm_base_modem_get_driver (MMBaseModem *self);
const gchar *mm_base_modem_get_plugin (MMBaseModem *self); const gchar *mm_base_modem_get_plugin (MMBaseModem *self);
@@ -149,4 +140,34 @@ const gchar *mm_base_modem_get_plugin (MMBaseModem *self);
guint mm_base_modem_get_vendor_id (MMBaseModem *self); guint mm_base_modem_get_vendor_id (MMBaseModem *self);
guint mm_base_modem_get_product_id (MMBaseModem *self); guint mm_base_modem_get_product_id (MMBaseModem *self);
void mm_base_modem_authorize (MMBaseModem *self,
GDBusMethodInvocation *invocation,
const gchar *authorization,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean mm_base_modem_authorize_finish (MMBaseModem *self,
GAsyncResult *res,
GError **error);
void mm_base_modem_initialize (MMBaseModem *self,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean mm_base_modem_initialize_finish (MMBaseModem *self,
GAsyncResult *res,
GError **error);
void mm_base_modem_enable (MMBaseModem *self,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean mm_base_modem_enable_finish (MMBaseModem *self,
GAsyncResult *res,
GError **error);
void mm_base_modem_disable (MMBaseModem *self,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean mm_base_modem_disable_finish (MMBaseModem *self,
GAsyncResult *res,
GError **error);
#endif /* MM_BASE_MODEM_H */ #endif /* MM_BASE_MODEM_H */

View File

@@ -1164,12 +1164,12 @@ enable_ready (MMBaseModem *self,
GError *error = NULL; GError *error = NULL;
if (ctx->enable) { if (ctx->enable) {
if (!MM_BASE_MODEM_GET_CLASS (self)->enable_finish (self, res, &error)) if (!mm_base_modem_enable_finish (self, res, &error))
g_dbus_method_invocation_take_error (ctx->invocation, error); g_dbus_method_invocation_take_error (ctx->invocation, error);
else else
mm_gdbus_modem_complete_enable (ctx->skeleton, ctx->invocation); mm_gdbus_modem_complete_enable (ctx->skeleton, ctx->invocation);
} else { } else {
if (!MM_BASE_MODEM_GET_CLASS (self)->disable_finish (self, res, &error)) if (!mm_base_modem_disable_finish (self, res, &error))
g_dbus_method_invocation_take_error (ctx->invocation, error); g_dbus_method_invocation_take_error (ctx->invocation, error);
else else
mm_gdbus_modem_complete_enable (ctx->skeleton, ctx->invocation); mm_gdbus_modem_complete_enable (ctx->skeleton, ctx->invocation);
@@ -1191,25 +1191,14 @@ handle_enable_auth_ready (MMBaseModem *self,
return; return;
} }
if (ctx->enable) { if (ctx->enable)
g_assert (MM_BASE_MODEM_GET_CLASS (self)->enable != NULL); mm_base_modem_enable (self,
g_assert (MM_BASE_MODEM_GET_CLASS (self)->enable_finish != NULL); (GAsyncReadyCallback)enable_ready,
ctx);
MM_BASE_MODEM_GET_CLASS (self)->enable ( else
self, mm_base_modem_disable (self,
NULL, /* cancellable */ (GAsyncReadyCallback)enable_ready,
(GAsyncReadyCallback)enable_ready, ctx);
ctx);
} else {
g_assert (MM_BASE_MODEM_GET_CLASS (self)->disable != NULL);
g_assert (MM_BASE_MODEM_GET_CLASS (self)->disable_finish != NULL);
MM_BASE_MODEM_GET_CLASS (self)->disable (
self,
NULL, /* cancellable */
(GAsyncReadyCallback)enable_ready,
ctx);
}
} }
static gboolean static gboolean
@@ -2010,11 +1999,7 @@ unlock_check_context_free (UnlockCheckContext *ctx)
static gboolean static gboolean
restart_initialize_idle (MMIfaceModem *self) restart_initialize_idle (MMIfaceModem *self)
{ {
MM_BASE_MODEM_GET_CLASS (self)->initialize ( mm_base_modem_initialize (MM_BASE_MODEM (self), NULL, NULL);
MM_BASE_MODEM (self),
NULL,
NULL,
NULL);
return FALSE; return FALSE;
} }