When SIGTERM is received, run the event loop
authorDenis Kenzior <denkenz@gmail.com>
Thu, 3 Dec 2009 01:08:31 +0000 (19:08 -0600)
committerDenis Kenzior <denkenz@gmail.com>
Thu, 3 Dec 2009 01:11:36 +0000 (19:11 -0600)
This feature will continue running the event loop for another 10 seconds
or so or until all the modems have been shut down.  This will allow the
modem drivers to properly shutdown their respective devices.

src/main.c
src/modem.c
src/ofono.h

index 7542e13..3b95e15 100644 (file)
 
 #include "ofono.h"
 
+#define SHUTDOWN_GRACE_SECONDS 10
+
 static GMainLoop *event_loop;
+static guint quit_eventloop_source = 0;
+
+void __ofono_exit()
+{
+       g_main_loop_quit(event_loop);
+}
+
+static gboolean quit_eventloop(gpointer user_data)
+{
+       __ofono_exit();
+       return FALSE;
+}
 
 static void sig_debug(int sig)
 {
@@ -42,7 +56,12 @@ static void sig_debug(int sig)
 
 static void sig_term(int sig)
 {
-       g_main_loop_quit(event_loop);
+       if (quit_eventloop_source != 0)
+               return;
+
+       quit_eventloop_source = g_timeout_add_seconds(SHUTDOWN_GRACE_SECONDS,
+                                                       quit_eventloop, NULL);
+       __ofono_modem_shutdown();
 }
 
 static void system_bus_disconnected(DBusConnection *conn, void *user_data)
index d44d080..9ac0c4c 100644 (file)
@@ -39,6 +39,8 @@ static GSList *g_driver_list = NULL;
 static GSList *g_modem_list = NULL;
 
 static int next_modem_id = 0;
+static gboolean powering_down = FALSE;
+static int modems_remaining = 0;
 
 enum ofono_property_type {
        OFONO_PROPERTY_TYPE_INVALID = 0,
@@ -478,6 +480,9 @@ static DBusMessage *modem_set_property(DBusConnection *conn,
        if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
                return __ofono_error_invalid_args(msg);
 
+       if (powering_down == TRUE)
+               return __ofono_error_failed(msg);
+
        dbus_message_iter_recurse(&iter, &var);
 
        if (g_str_equal(name, "Powered") == TRUE) {
@@ -539,7 +544,6 @@ static GDBusSignalTable modem_signals[] = {
 void ofono_modem_set_powered(struct ofono_modem *modem, ofono_bool_t powered)
 {
        DBusConnection *conn = ofono_dbus_get_connection();
-       dbus_bool_t dbus_powered;
 
        if (modem->timeout > 0) {
                g_source_remove(modem->timeout);
@@ -559,23 +563,29 @@ void ofono_modem_set_powered(struct ofono_modem *modem, ofono_bool_t powered)
 
        modem->powered_pending = powered;
 
-       if (modem->powered == powered)
-               return;
+       if (modem->powered != powered) {
+               modem->powered = powered;
 
-       modem->powered = powered;
+               if (modem->driver) {
+                       dbus_bool_t dbus_powered = powered;
 
-       if (modem->driver == NULL)
-               return;
-
-       dbus_powered = powered;
-       ofono_dbus_signal_property_changed(conn, modem->path,
+                       ofono_dbus_signal_property_changed(conn, modem->path,
                                                OFONO_MODEM_INTERFACE,
                                                "Powered", DBUS_TYPE_BOOLEAN,
                                                &dbus_powered);
+               }
 
-       if (powered) {
-               if (modem->driver->pre_sim)
-                       modem->driver->pre_sim(modem);
+               if (powered) {
+                       if (modem->driver->pre_sim)
+                               modem->driver->pre_sim(modem);
+               }
+       }
+
+       if (powering_down) {
+               modems_remaining -= 1;
+
+               if (modems_remaining == 0)
+                       __ofono_exit();
        }
 }
 
@@ -1099,6 +1109,9 @@ int ofono_modem_register(struct ofono_modem *modem)
        if (modem == NULL)
                return -EINVAL;
 
+       if (powering_down == TRUE)
+               return -EBUSY;
+
        if (modem->driver != NULL)
                return -EALREADY;
 
@@ -1246,3 +1259,26 @@ void ofono_modem_driver_unregister(const struct ofono_modem_driver *d)
                modem_unregister(modem);
        }
 }
+
+void __ofono_modem_shutdown()
+{
+       struct ofono_modem *modem;
+       GSList *l;
+
+       powering_down = TRUE;
+
+       for (l = g_modem_list; l; l = l->next) {
+               modem = l->data;
+
+               modem = l->data;
+
+               if (modem->driver == NULL)
+                       continue;
+
+               if (modem->powered == FALSE && modem->powered_pending == FALSE)
+                       continue;
+
+               if (set_powered(modem, FALSE) == -EINPROGRESS)
+                       modems_remaining += 1;
+       }
+}
index 266ed88..b05320e 100644 (file)
 
 #define OFONO_API_SUBJECT_TO_CHANGE
 
+void __ofono_exit();
+
 int __ofono_manager_init();
 void __ofono_manager_cleanup();
 
 const char **__ofono_modem_get_list();
+void __ofono_modem_shutdown();
 
 #include <ofono/log.h>