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 *); | 
