diff options
Diffstat (limited to 'src/glibext')
-rw-r--r-- | src/glibext/delayed.c | 74 | ||||
-rw-r--r-- | src/glibext/delayed.h | 5 |
2 files changed, 34 insertions, 45 deletions
diff --git a/src/glibext/delayed.c b/src/glibext/delayed.c index 9d67a7c..9bac68a 100644 --- a/src/glibext/delayed.c +++ b/src/glibext/delayed.c @@ -175,7 +175,7 @@ static void g_work_queue_dispose(GWorkQueue *); static void g_work_queue_finalize(GWorkQueue *); /* Donne l'assurance de l'existence d'un groupe de travail. */ -static GWorkGroup *g_work_queue_ensure_group_exists(GWorkQueue *, wgroup_id_t); +static bool g_work_queue_ensure_group_exists(GWorkQueue *, wgroup_id_t); /* Fournit le groupe de travail correspondant à un identifiant. */ static GWorkGroup *g_work_queue_find_group_for_id(GWorkQueue *, wgroup_id_t); @@ -682,13 +682,11 @@ static bool g_work_group_is_empty(GWorkGroup *group) * son utilisation par l'appelant. * * Il doit donc logiquement y avoir un autre verrou en amont et, - * comme à priori on ne devrait pas bloquer le groupe principal - * pour un traitement particulier, on ajoute ici une simple vérification - * de bonne pratique. + * comme à priori on ne devrait pas bloquer les groupes principaux + * pour un traitement particulier, cette procédure ne devrait concerner + * que des groupes dynamiques. */ - assert(group->id != DEFAULT_WORK_GROUP); - g_mutex_lock(&group->mutex); result = dl_list_empty(group->works); @@ -936,24 +934,26 @@ GWorkQueue *g_work_queue_new(void) * * * Description : Donne l'assurance de l'existence d'un groupe de travail. * * * -* Retour : - * +* Retour : true si un nouveau groupe a été constitué, false sinon. * * * * Remarques : Le verrou d'accès doit être posé par l'appelant. * * * ******************************************************************************/ -static GWorkGroup *g_work_queue_ensure_group_exists(GWorkQueue *queue, wgroup_id_t id) +static bool g_work_queue_ensure_group_exists(GWorkQueue *queue, wgroup_id_t id) { - GWorkGroup *result; /* Groupe en place à renvoyer */ bool found; /* Bilan des recherches */ size_t i; /* Boucle de parcours */ + GWorkGroup *group; /* Groupe à consulter */ + + assert(!g_mutex_trylock(&queue->mutex)); found = false; for (i = 0; i < queue->groups_count && !found; i++) { - result = queue->groups[i]; - found = (g_work_group_get_id(result) == id); + group = queue->groups[i]; + found = (g_work_group_get_id(group) == id); } if (!found) @@ -962,12 +962,12 @@ static GWorkGroup *g_work_queue_ensure_group_exists(GWorkQueue *queue, wgroup_id queue->groups = (GWorkGroup **)realloc(queue->groups, queue->groups_count * sizeof(GWorkGroup *)); - result = g_work_group_new(id); - queue->groups[queue->groups_count - 1] = result; + group = g_work_group_new(id); + queue->groups[queue->groups_count - 1] = group; } - return result; + return !found; } @@ -987,12 +987,16 @@ static GWorkGroup *g_work_queue_ensure_group_exists(GWorkQueue *queue, wgroup_id wgroup_id_t g_work_queue_define_work_group(GWorkQueue *queue) { wgroup_id_t result; /* Valeur à retourner */ + bool created; /* Bilan d'une tentative */ g_mutex_lock(&queue->mutex); - result = ++queue->generator; - - g_work_queue_ensure_group_exists(queue, result); + do + { + result = queue->generator++; + created = g_work_queue_ensure_group_exists(queue, result); + } + while (!created); g_mutex_unlock(&queue->mutex); @@ -1072,13 +1076,8 @@ void g_work_queue_schedule_work(GWorkQueue *queue, GDelayedWork *work, wgroup_id { GWorkGroup *group; /* Groupe de travail à attendre*/ - g_mutex_lock(&queue->mutex); - - group = g_work_queue_ensure_group_exists(queue, id); - - g_object_ref(G_OBJECT(group)); - - g_mutex_unlock(&queue->mutex); + group = g_work_queue_find_group_for_id(queue, id); + assert(group != NULL); g_work_group_schedule(group, work); @@ -1188,7 +1187,9 @@ void g_work_queue_wait_for_completion(GWorkQueue *queue, wgroup_id_t id) /****************************************************************************** * * -* Paramètres : queue = gestionnaire de l'ensemble des groupes de travail. * +* Paramètres : queue = gestionnaire de l'ensemble des groupes de travail.* +* gb_ids = identifiants de groupes globaux. * +* gb_count = nombre de ces groupes globaux. * * * * Description : Attend que toutes les tâches de tout groupe soient traitées. * * * @@ -1198,36 +1199,29 @@ void g_work_queue_wait_for_completion(GWorkQueue *queue, wgroup_id_t id) * * ******************************************************************************/ -void g_work_queue_wait_for_all_completions(GWorkQueue *queue) +void g_work_queue_wait_for_all_completions(GWorkQueue *queue, const wgroup_id_t *gb_ids, size_t gb_count) { - GWorkGroup *def_group; /* Groupe de travail par défaut*/ + size_t i; /* Boucle de parcours */ 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) + while (queue->groups_count > gb_count) g_cond_wait(&queue->wait_all, &queue->mutex); g_mutex_unlock(&queue->mutex); /** - * Attente du groupe principal. + * Attente des groupes principaux. */ - g_work_queue_wait_for_completion(queue, DEFAULT_WORK_GROUP); + for (i = 0; i < gb_count; i++) + g_work_queue_wait_for_completion(queue, gb_ids[i]); /** * Si le groupe par défaut a généré de nouveaux groupes, on recommence ! @@ -1235,13 +1229,11 @@ void g_work_queue_wait_for_all_completions(GWorkQueue *queue) g_mutex_lock(&queue->mutex); - if (queue->groups_count > 1) + if (queue->groups_count > gb_count) goto wait_again; g_mutex_unlock(&queue->mutex); - g_object_unref(G_OBJECT(def_group)); - } diff --git a/src/glibext/delayed.h b/src/glibext/delayed.h index 340a298..c22cc5a 100644 --- a/src/glibext/delayed.h +++ b/src/glibext/delayed.h @@ -82,9 +82,6 @@ typedef struct _GWorkQueueClass GWorkQueueClass; /* Identifiant unique pour groupe de travail */ typedef unsigned long long wgroup_id_t; -/* Groupe d'exécution par défaut */ -#define DEFAULT_WORK_GROUP 0 - /* Indique le type défini pour le gestionnaire des travaux différés. */ GType g_work_queue_get_type(void); @@ -108,7 +105,7 @@ bool g_work_queue_is_empty(GWorkQueue *, wgroup_id_t); 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 *); +void g_work_queue_wait_for_all_completions(GWorkQueue *, const wgroup_id_t *, size_t); /* Etudie le besoin d'attendre d'avantage de prochaines tâches. */ |