summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDenis Kenzior <denkenz@gmail.com>2010-12-22 14:02:59 -0600
committerDenis Kenzior <denkenz@gmail.com>2010-12-22 14:02:59 -0600
commit3daf20216f3e16c65cc5142405477a141f64c9c3 (patch)
treeb74d5a4e3151d5d03ead48bd5ccb0092f8e86cf3 /src
parent1a15548799d4b1836b5741902efa2332a25b47ed (diff)
downloadofono-3daf20216f3e16c65cc5142405477a141f64c9c3.tar.bz2
modem: Implement some race-condition avoidance
Diffstat (limited to 'src')
-rw-r--r--src/modem.c43
1 files changed, 39 insertions, 4 deletions
diff --git a/src/modem.c b/src/modem.c
index 6d18e99e..4436f713 100644
--- a/src/modem.c
+++ b/src/modem.c
@@ -462,6 +462,42 @@ void __ofono_modem_remove_online_watch(struct ofono_modem *modem,
__ofono_watchlist_remove_item(modem->online_watches, id);
}
+static void common_online_cb(const struct ofono_error *error, void *data)
+{
+ struct ofono_modem *modem = data;
+
+ if (error->type != OFONO_ERROR_TYPE_NO_ERROR)
+ return;
+
+ /*
+ * If we need to get online after a silent reset this callback
+ * is called. The callback should not consider the pending dbus
+ * message.
+ *
+ * Additionally, this process can be interrupted by the following
+ * events:
+ * - Sim being removed
+ * - SetProperty(Powered, False) being called
+ * - SetProperty(Lockdown, True) being called
+ *
+ * We should not set the modem to the online state in these cases.
+ */
+ switch (modem->modem_state) {
+ case MODEM_STATE_OFFLINE:
+ modem_change_state(modem, MODEM_STATE_ONLINE);
+ break;
+ case MODEM_STATE_POWER_OFF:
+ /* The powered operation is pending */
+ break;
+ case MODEM_STATE_PRE_SIM:
+ modem->driver->set_online(modem, 1, NULL, NULL);
+ break;
+ case MODEM_STATE_ONLINE:
+ ofono_error("Online called when the modem is already online!");
+ break;
+ };
+}
+
static void online_cb(const struct ofono_error *error, void *data)
{
struct ofono_modem *modem = data;
@@ -479,9 +515,7 @@ static void online_cb(const struct ofono_error *error, void *data)
__ofono_dbus_pending_reply(&modem->pending, reply);
out:
- if (error->type == OFONO_ERROR_TYPE_NO_ERROR &&
- modem->modem_state == MODEM_STATE_OFFLINE)
- modem_change_state(modem, MODEM_STATE_ONLINE);
+ common_online_cb(error, data);
}
static void offline_cb(const struct ofono_error *error, void *data)
@@ -521,7 +555,8 @@ static void sim_state_watch(enum ofono_sim_state new_state, void *user)
if (modem->driver->set_online == NULL)
modem_change_state(modem, MODEM_STATE_ONLINE);
else if (modem->get_online)
- modem->driver->set_online(modem, 1, online_cb, modem);
+ modem->driver->set_online(modem, 1, common_online_cb,
+ modem);
modem->get_online = FALSE;