summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/glibext/delayed.c60
1 files changed, 60 insertions, 0 deletions
diff --git a/src/glibext/delayed.c b/src/glibext/delayed.c
index d05b67a..9d67a7c 100644
--- a/src/glibext/delayed.c
+++ b/src/glibext/delayed.c
@@ -442,8 +442,17 @@ static void g_work_group_dispose(GWorkGroup *group)
group->force_exit = true;
+ /**
+ * Concernant la pose du verrou, se référer aux commentaires de la
+ * fonction g_work_group_process().
+ */
+
+ g_mutex_lock(&group->mutex);
+
g_cond_broadcast(&group->cond);
+ g_mutex_unlock(&group->mutex);
+
for (i = 0; i < group->threads_count; i++)
g_thread_join(group->threads[i]);
@@ -599,9 +608,51 @@ static void *g_work_group_process(GWorkGroup *group)
g_object_unref(G_OBJECT(work));
+ /**
+ * Verrou ou pas verrou ?
+ *
+ * La documentation de la GLib indique que ce n'est pas nécessaire :
+ *
+ * '''
+ * It is good practice to lock the same mutex as the waiting threads
+ * while calling this function, though not required.
+ * '''
+ *
+ * Ce conseil se trouve verbatim à l'adresse :
+ *
+ * https://developer.gnome.org/glib/stable/glib-Threads.html#g-cond-broadcast
+ *
+ * Dans la pratique, il peut arriver que l'attente de la fonction
+ * g_work_group_wait_for_completion() ne soit jamais interrompue.
+ *
+ * La documentation POSIX est un peu plus orientée :
+ *
+ * '''
+ * The pthread_cond_broadcast() functions may be called by a thread
+ * whether or not it currently owns the mutex that threads calling
+ * pthread_cond_wait() have associated with the condition variable
+ * during their waits; however, if predictable scheduling behavior is
+ * required, then that mutex shall be locked by the thread calling
+ * pthread_cond_broadcast().
+ * '''
+ *
+ * Ce passage complet est consultable à l'adresse :
+ *
+ * http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_cond_broadcast.html
+ *
+ * La page de manuel pthread_cond_broadcast(3) est quant à elle plus
+ * directrice : aucun complément d'information sur le sujet n'est fourni
+ * et les exemples associés utilisent implicement un verrou pendant
+ * sont appel.
+ */
+
+ g_mutex_lock(&group->mutex);
+
if (g_atomic_int_dec_and_test(&group->pending))
g_cond_broadcast(&group->wait_cond);
+ g_mutex_unlock(&group->mutex);
+
}
return NULL;
@@ -730,8 +781,17 @@ static void g_work_group_set_extra_wait_callback(GWorkGroup *group, wait_for_inc
static void g_work_group_wake_up_waiters(GWorkGroup *group)
{
+ /**
+ * Concernant la pose du verrou, se référer aux commentaires de la
+ * fonction g_work_group_process().
+ */
+
+ g_mutex_lock(&group->mutex);
+
g_cond_broadcast(&group->wait_cond);
+ g_mutex_unlock(&group->mutex);
+
}