From df105a6b09937a73ee2710593f144e4888443870 Mon Sep 17 00:00:00 2001 From: Simo Piiroinen Date: Thu, 7 Jul 2016 09:32:24 +0300 Subject: [PATCH] [appsync] Stop post-enum apps before stopping pre-enum apps. JB#35683 When appsync is starting applications, pre-enum applications are started before post-enum apps. However stopping applications is done in whatever order they happen to be after configuration parsing - which could cause problems if post apps have explicit dependencies on pre apps. Do also application stopping in two phases: first post-enum apps followed by pre-enum apps. Also, apart from usb-moded startup/shutdown, attempt to skip stopping of applications that have not been started. Signed-off-by: Simo Piiroinen --- src/usb_moded-appsync.c | 45 ++++++++++++++++++++++++++++--------- src/usb_moded-appsync.h | 2 +- src/usb_moded-modesetting.c | 3 ++- src/usb_moded.c | 4 ++-- 4 files changed, 40 insertions(+), 14 deletions(-) diff --git a/src/usb_moded-appsync.c b/src/usb_moded-appsync.c index 2d1136f..ff79dfb 100644 --- a/src/usb_moded-appsync.c +++ b/src/usb_moded-appsync.c @@ -253,10 +253,9 @@ int activate_sync(const char *mode) /* do not launch items marked as post, will be launched after usb is up */ if(data->post) { - mark_active(data->name, data->post); continue; } - log_debug("launching app %s\n", data->name); + log_debug("launching pre-enum-app %s\n", data->name); if(data->systemd) { if(!systemd_control_service(data->name, SYSTEMD_START)) @@ -318,11 +317,12 @@ int activate_sync_post(const char *mode) /* launch only items marked as post, others are already running */ if(!data->post) continue; - log_debug("launching app %s\n", data->name); + log_debug("launching post-enum-app %s\n", data->name); if(data->systemd) { if(systemd_control_service(data->name, SYSTEMD_START)) goto error; + mark_active(data->name, 1); } else if(data->launch) { @@ -353,12 +353,12 @@ int mark_active(const gchar *name, int post) GList *iter; - if(post) - log_debug("App %s notified it is ready\n", name); + log_debug("%s-enum-app %s is started\n", post ? "post" : "pre", name); for( iter = sync_list; iter; iter = g_list_next(iter) ) { struct list_elem *data = iter->data; + if(!strcmp(data->name, name)) { /* TODO: do we need to worry about duplicate names in the list? */ @@ -368,7 +368,7 @@ int mark_active(const gchar *name, int post) /* updated + missing -> not going to enumerate */ if( missing ) break; } - else if( data->active == 0 ) + else if( data->active == 0 && data->post == post ) { missing = 1; @@ -376,9 +376,9 @@ int mark_active(const gchar *name, int post) if( ret != -1 ) break; } } - if( !missing ) + if( !post && !missing ) { - log_debug("All apps active. Let's enumerate\n"); + log_debug("All pre-enum-apps active. Let's enumerate\n"); enumerate_usb(); } @@ -446,7 +446,7 @@ static void enumerate_usb(void) } } -int appsync_stop(void) +static void appsync_stop_apps(int post) { GList *iter = 0; @@ -454,13 +454,38 @@ int appsync_stop(void) { struct list_elem *data = iter->data; - if(data->systemd) + if(data->systemd && data->active && data->post == post) { + log_debug("stopping %s-enum-app %s", post ? "post" : "pre", data->name); if(systemd_control_service(data->name, SYSTEMD_STOP)) log_debug("Failed to stop %s\n", data->name); + data->active = 0; + } + } +} + +int appsync_stop(int force) +{ + /* If force arg is used, stop all applications that + * could have been started by usb-moded */ + if(force) + { + GList *iter; + log_debug("assuming all applications are active"); + + for( iter = sync_list; iter; iter = g_list_next(iter) ) + { + struct list_elem *data = iter->data; + data->active = 1; } } + /* Stop post-apps 1st */ + appsync_stop_apps(1); + + /* Then pre-apps */ + appsync_stop_apps(0); + /* Do not leave active timers behind */ cancel_enumerate_usb_timer(); return(0); diff --git a/src/usb_moded-appsync.h b/src/usb_moded-appsync.h index 14ae85c..0c33b93 100644 --- a/src/usb_moded-appsync.h +++ b/src/usb_moded-appsync.h @@ -48,6 +48,6 @@ void readlist(int diag); int activate_sync(const char *mode); int activate_sync_post(const char *mode); int mark_active(const gchar *name, int post); -int appsync_stop(void); +int appsync_stop(int force); void free_appsync_list(void); void usb_moded_appsync_cleanup(void); diff --git a/src/usb_moded-modesetting.c b/src/usb_moded-modesetting.c index 61e2eb1..6d01f26 100644 --- a/src/usb_moded-modesetting.c +++ b/src/usb_moded-modesetting.c @@ -566,7 +566,8 @@ int usb_moded_mode_cleanup(const char *module) } #ifdef APP_SYNC - appsync_stop(); + /* Stop applications started due to entering this mode */ + appsync_stop(0); #endif /* APP_SYNC */ if(!strcmp(module, MODULE_MASS_STORAGE)|| !strcmp(module, MODULE_FILE_STORAGE)) diff --git a/src/usb_moded.c b/src/usb_moded.c index 44f85bb..382b6a0 100644 --- a/src/usb_moded.c +++ b/src/usb_moded.c @@ -623,7 +623,7 @@ static void usb_moded_init(void) #ifdef APP_SYNC readlist(diag_mode); /* make sure all services are down when starting */ - appsync_stop(); + appsync_stop(1); modelist = read_mode_list(diag_mode); #endif /* APP_SYNC */ @@ -670,7 +670,7 @@ static gboolean charging_fallback(gpointer data) static void handle_exit(void) { /* exiting and clean-up when mainloop ended */ - appsync_stop(); + appsync_stop(1); hwal_cleanup(); usb_moded_dbus_cleanup(); #ifdef MEEGOLOCK