summaryrefslogtreecommitdiff
path: root/src/glibext
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2018-04-22 15:23:01 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2018-04-22 15:23:01 (GMT)
commit01402277db54d9fddaa12878f6db7f02c8d8e7ef (patch)
tree694dcf1dc464177b3e01a6043a48ccb7721e054b /src/glibext
parent40c139384b25e89f9308f0d493e1c9ff0318a3cb (diff)
Ensured all tasks are completed before exiting batch mode.
Diffstat (limited to 'src/glibext')
-rw-r--r--src/glibext/delayed.c64
-rw-r--r--src/glibext/delayed.h3
2 files changed, 67 insertions, 0 deletions
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 *);