From 01402277db54d9fddaa12878f6db7f02c8d8e7ef Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sun, 22 Apr 2018 17:23:01 +0200 Subject: Ensured all tasks are completed before exiting batch mode. --- src/analysis/project.c | 8 ++++--- src/glibext/delayed.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/glibext/delayed.h | 3 +++ src/main.c | 2 +- 4 files changed, 73 insertions(+), 4 deletions(-) diff --git a/src/analysis/project.c b/src/analysis/project.c index 88b468a..b4108ff 100644 --- a/src/analysis/project.c +++ b/src/analysis/project.c @@ -999,14 +999,16 @@ static void on_loaded_content_analyzed(GLoadedContent *content, gboolean success { const char *desc; /* Description du contenu */ + desc = g_loaded_content_describe(content, true); + if (success) + { g_study_project_attach_content(project, content); + log_variadic_message(LMT_INFO, _("Content from '%s' has been analyzed successfully!"), desc); + } else - { - desc = g_loaded_content_describe(content, true); log_variadic_message(LMT_ERROR, _("Failed to load '%s'"), desc); - } g_object_ref(G_OBJECT(content)); diff --git a/src/glibext/delayed.c b/src/glibext/delayed.c index 78c8a10..d05b67a 100644 --- a/src/glibext/delayed.c +++ b/src/glibext/delayed.c @@ -150,6 +150,7 @@ struct _GWorkQueue GWorkGroup **groups; /* Files de traitement */ size_t groups_count; /* Nombre de files internes */ GMutex mutex; /* Verrou pour l'accès */ + GCond wait_all; /* Réveil d'attente globale */ }; @@ -787,6 +788,7 @@ static void g_work_queue_init(GWorkQueue *queue) queue->groups = NULL; queue->groups_count = 0; g_mutex_init(&queue->mutex); + g_cond_init(&queue->wait_all); } @@ -815,6 +817,7 @@ static void g_work_queue_dispose(GWorkQueue *queue) g_mutex_unlock(&queue->mutex); g_mutex_clear(&queue->mutex); + g_cond_clear(&queue->wait_all); G_OBJECT_CLASS(g_work_queue_parent_class)->dispose(G_OBJECT(queue)); @@ -984,6 +987,8 @@ void g_work_queue_delete_work_group(GWorkQueue *queue, wgroup_id_t id) assert(found); + g_cond_broadcast(&queue->wait_all); + g_mutex_unlock(&queue->mutex); } @@ -1123,6 +1128,65 @@ void g_work_queue_wait_for_completion(GWorkQueue *queue, wgroup_id_t id) /****************************************************************************** * * +* Paramètres : queue = gestionnaire de l'ensemble des groupes de travail. * +* * +* Description : Attend que toutes les tâches de tout groupe soient traitées. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_work_queue_wait_for_all_completions(GWorkQueue *queue) +{ + GWorkGroup *def_group; /* Groupe de travail par défaut*/ + + g_mutex_lock(&queue->mutex); + + /** + * Récupération du groupe par défaut. + */ + + def_group = g_work_queue_ensure_group_exists(queue, DEFAULT_WORK_GROUP); + + g_object_ref(G_OBJECT(def_group)); + + wait_again: + + /** + * Attente d'éventuels groupes isolés. + */ + + while (queue->groups_count > 1) + g_cond_wait(&queue->wait_all, &queue->mutex); + + g_mutex_unlock(&queue->mutex); + + /** + * Attente du groupe principal. + */ + + g_work_queue_wait_for_completion(queue, DEFAULT_WORK_GROUP); + + /** + * Si le groupe par défaut a généré de nouveaux groupes, on recommence ! + */ + + g_mutex_lock(&queue->mutex); + + if (queue->groups_count > 1) + goto wait_again; + + g_mutex_unlock(&queue->mutex); + + g_object_unref(G_OBJECT(def_group)); + +} + + +/****************************************************************************** +* * * Paramètres : queue = gestionnaire de l'ensemble des groupes de travail.* * id = identifiant d'un groupe de travail. * * callback = éventuelle fonction à appeler ou NULL. * diff --git a/src/glibext/delayed.h b/src/glibext/delayed.h index ab43640..340a298 100644 --- a/src/glibext/delayed.h +++ b/src/glibext/delayed.h @@ -107,6 +107,9 @@ bool g_work_queue_is_empty(GWorkQueue *, wgroup_id_t); /* Attend que toutes les tâches d'un groupe soient traitées. */ void g_work_queue_wait_for_completion(GWorkQueue *, wgroup_id_t); +/* Attend que toutes les tâches de tout groupe soient traitées. */ +void g_work_queue_wait_for_all_completions(GWorkQueue *); + /* Etudie le besoin d'attendre d'avantage de prochaines tâches. */ typedef bool (* wait_for_incoming_works_cb) (GWorkQueue *, wgroup_id_t, void *); diff --git a/src/main.c b/src/main.c index 626cae8..0abc29f 100644 --- a/src/main.c +++ b/src/main.c @@ -340,7 +340,7 @@ int main(int argc, char **argv) result = open_binaries(argv + optind, argc - optind); if (batch_mode) - g_work_queue_wait_for_completion(get_work_queue(), DEFAULT_WORK_GROUP); + g_work_queue_wait_for_all_completions(get_work_queue()); else gtk_main(); -- cgit v0.11.2-87-g4458