iface-modem: new helper method to wait until a final state is reached

This commit is contained in:
Aleksander Morgado
2012-10-30 15:35:33 +01:00
parent 96986117b3
commit 4fc3f52791
2 changed files with 137 additions and 0 deletions
+128
View File
@@ -74,6 +74,134 @@ mm_iface_modem_bind_simple_status (MMIfaceModem *self,
g_object_unref (skeleton);
}
/*****************************************************************************/
/* Helper method to wait for a final state */
#define MODEM_STATE_IS_INTERMEDIATE(state) \
(state == MM_MODEM_STATE_INITIALIZING || \
state == MM_MODEM_STATE_INITIALIZING || \
state == MM_MODEM_STATE_INITIALIZING || \
state == MM_MODEM_STATE_INITIALIZING || \
state == MM_MODEM_STATE_INITIALIZING)
typedef struct {
MMIfaceModem *self;
MMModemState final_state;
GSimpleAsyncResult *result;
gulong state_changed_id;
guint state_changed_wait_id;
} WaitForFinalStateContext;
static void
wait_for_final_state_context_complete_and_free (WaitForFinalStateContext *ctx)
{
g_simple_async_result_complete (ctx->result);
g_object_unref (ctx->result);
g_signal_handler_disconnect (ctx->self, ctx->state_changed_id);
g_source_remove (ctx->state_changed_wait_id);
g_object_unref (ctx->self);
g_slice_free (WaitForFinalStateContext, ctx);
}
MMModemState
mm_iface_modem_wait_for_final_state_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error)
{
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
return MM_MODEM_STATE_UNKNOWN;
return (MMModemState)GPOINTER_TO_UINT (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
}
static gboolean
state_changed_wait_expired (WaitForFinalStateContext *ctx)
{
g_simple_async_result_set_error (
ctx->result,
MM_CORE_ERROR,
MM_CORE_ERROR_RETRY,
"Too much time waiting to get to a final state");
wait_for_final_state_context_complete_and_free (ctx);
return FALSE;
}
static void
state_changed (MMIfaceModem *self,
GParamSpec *spec,
WaitForFinalStateContext *ctx)
{
MMModemState state = MM_MODEM_STATE_UNKNOWN;
g_object_get (self,
MM_IFACE_MODEM_STATE, &state,
NULL);
/* Are we in a final state already? */
if (MODEM_STATE_IS_INTERMEDIATE (state))
return;
/* If we want a specific final state and this is not the one we were
* looking for, then skip */
if (ctx->final_state != MM_MODEM_STATE_UNKNOWN &&
state != MM_MODEM_STATE_UNKNOWN &&
state != ctx->final_state)
return;
/* Done! */
g_simple_async_result_set_op_res_gpointer (ctx->result, GUINT_TO_POINTER (state), NULL);
wait_for_final_state_context_complete_and_free (ctx);
}
void
mm_iface_modem_wait_for_final_state (MMIfaceModem *self,
MMModemState final_state,
GAsyncReadyCallback callback,
gpointer user_data)
{
MMModemState state = MM_MODEM_STATE_UNKNOWN;
WaitForFinalStateContext *ctx;
GSimpleAsyncResult *result;
result = g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
mm_iface_modem_wait_for_final_state);
g_object_get (self,
MM_IFACE_MODEM_STATE, &state,
NULL);
/* Are we in a final state already? */
if (!MODEM_STATE_IS_INTERMEDIATE (state)) {
/* Is this the state we actually wanted? */
if (final_state == MM_MODEM_STATE_UNKNOWN ||
(state != MM_MODEM_STATE_UNKNOWN && state == final_state)) {
g_simple_async_result_set_op_res_gpointer (result, GUINT_TO_POINTER (state), NULL);
g_simple_async_result_complete_in_idle (result);
g_object_unref (result);
return;
}
/* Otherwise, we'll need to wait for the exact one we want */
}
ctx = g_slice_new0 (WaitForFinalStateContext);
ctx->result = result;
ctx->self = g_object_ref (self);
ctx->final_state = final_state;
/* Want to get notified when modem state changes */
ctx->state_changed_id = g_signal_connect (ctx->self,
"notify::" MM_IFACE_MODEM_STATE,
G_CALLBACK (state_changed),
ctx);
/* But we don't want to wait forever */
ctx->state_changed_wait_id = g_timeout_add_seconds (10,
(GSourceFunc)state_changed_wait_expired,
ctx);
}
/*****************************************************************************/
static MMModemState get_current_consolidated_state (MMIfaceModem *self);
+9
View File
@@ -437,6 +437,15 @@ MMBearer *mm_iface_modem_create_bearer_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error);
/* Helper method to wait for a final state */
void mm_iface_modem_wait_for_final_state (MMIfaceModem *self,
MMModemState final_state,
GAsyncReadyCallback callback,
gpointer user_data);
MMModemState mm_iface_modem_wait_for_final_state_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error);
void mm_iface_modem_bind_simple_status (MMIfaceModem *self,
MMSimpleStatus *status);