diff options
Diffstat (limited to 'src/glibext')
-rw-r--r-- | src/glibext/delayed.c | 64 | ||||
-rw-r--r-- | src/glibext/delayed.h | 3 |
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 *); |