Skip to content
Permalink
Browse files
[usb-moded] Fix issues on exit path. MER#1694
Exiting from mainloop does not work as intended, looks like handle_exit()
is meant to be called from main() function after mainloop is stopped. What
happens in practice is that handle_exit() gets called from signal handler
and it makes exit() without ever returning to main() function - which
means some cleanup tasks are skipped.

In general: Make cleanup tasks happen on the same logical level where
initialization is made, re-order init/cleanup tasks according to what
functional inter dependencies exist and add comments describing why
things are done when they are done.

Remove handle_exit() function and distribute work it used to do among:
- usb_moded_stop() - exiting from mainloop
- usb_moded_cleanup() - releasing usb-mode related state/config data
- main() - cleaning up init steps made from main()

To make possible ordering issues more visible, refuse to send usb-moded
dbus signals in situations where the service name is not owned by the
ubs-moded process.

Signed-off-by: Simo Piiroinen <simo.piiroinen@jollamobile.com>
  • Loading branch information
spiiroin committed Nov 7, 2016
1 parent c9055d0 commit b3e2f3700ef4dd15056d7608a105ef29903fb19e
Showing with 251 additions and 116 deletions.
  1. +46 −12 src/usb_moded-dbus.c
  2. +201 −103 src/usb_moded.c
  3. +4 −1 src/usb_moded.h
@@ -45,6 +45,8 @@
#define INIT_DONE_MATCH "type='signal',interface='"INIT_DONE_INTERFACE"',member='"INIT_DONE_SIGNAL"'"

static DBusConnection *dbus_connection_sys = NULL;
static gboolean have_service_name = FALSE;

extern gboolean rescue_mode;

/**
@@ -53,7 +55,12 @@ extern gboolean rescue_mode;
static void usb_moded_send_config_signal(const char *section, const char *key, const char *value)
{
log_debug(USB_MODE_CONFIG_SIGNAL_NAME ": %s %s %s\n", section, key, value);
if (dbus_connection_sys)
if( !have_service_name )
{
log_err("config notification without service: [%s] %s=%s",
section, key, value);
}
else if (dbus_connection_sys)
{
DBusMessage* msg = dbus_message_new_signal(USB_MODE_OBJECT, USB_MODE_INTERFACE, USB_MODE_CONFIG_SIGNAL_NAME);
if (msg) {
@@ -536,6 +543,8 @@ gboolean usb_moded_dbus_init_service(void)
log_debug("DBUS ERROR: %s, %s \n", error.name, error.message);
goto EXIT;
}
log_debug("claimed name %s", USB_MODE_SERVICE);
have_service_name = TRUE;
/* everything went fine */
status = TRUE;

@@ -544,23 +553,42 @@ gboolean usb_moded_dbus_init_service(void)
return status;
}

/** Release "com.meego.usb_moded" D-Bus Service Name
*/
static void usb_moded_dbus_cleanup_service(void)
{
if( !have_service_name )
goto EXIT;

have_service_name = FALSE;
log_debug("release name %s", USB_MODE_SERVICE);

if( dbus_connection_sys &&
dbus_connection_get_is_connected(dbus_connection_sys) )
{
dbus_bus_release_name(dbus_connection_sys, USB_MODE_SERVICE, NULL);
}

EXIT:
return;
}

/**
* Clean up the dbus connections on exit
*
*/
void usb_moded_dbus_cleanup(void)
{
/* clean up system bus connection */
if (dbus_connection_sys != NULL)
{
if( dbus_connection_get_is_connected(dbus_connection_sys) ) {
// FIXME: do we want to do this? It is pretty useless on exit path.
dbus_bus_release_name(dbus_connection_sys, USB_MODE_SERVICE, NULL);
}
dbus_connection_remove_filter(dbus_connection_sys, msg_handler, NULL);
dbus_connection_unref(dbus_connection_sys);
dbus_connection_sys = NULL;
}
/* clean up system bus connection */
if (dbus_connection_sys != NULL)
{
usb_moded_dbus_cleanup_service();

dbus_connection_remove_filter(dbus_connection_sys, msg_handler, NULL);

dbus_connection_unref(dbus_connection_sys),
dbus_connection_sys = NULL;
}
}

/**
@@ -575,6 +603,12 @@ static int usb_moded_dbus_signal(const char *signal_type, const char *content)
int result = 1;
DBusMessage* msg = 0;

if( !have_service_name )
{
log_err("sending signal without service: %s(%s)",
signal_type, content);
goto EXIT;
}
if(!dbus_connection_sys)
{
log_err("Dbus system connection broken!\n");

0 comments on commit b3e2f37

Please sign in to comment.