summaryrefslogtreecommitdiffstats
path: root/libdimension/progress.c
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@gmail.com>2009-10-26 00:54:15 +0000
committerTavian Barnes <tavianator@gmail.com>2009-10-26 00:54:15 +0000
commit0bb6bfe0b08eb9fc2ba62f64bdb21cb5b592c292 (patch)
treee7ef618a917290a530cc2faec586724ac0265a60 /libdimension/progress.c
parent75f20754030726569ac8cbc243628c18e523f3bb (diff)
downloaddimension-0bb6bfe0b08eb9fc2ba62f64bdb21cb5b592c292.tar.xz
Fix some concurrency mistakes.
TODO: eliminate the too_late field on canvases.
Diffstat (limited to 'libdimension/progress.c')
-rw-r--r--libdimension/progress.c38
1 files changed, 27 insertions, 11 deletions
diff --git a/libdimension/progress.c b/libdimension/progress.c
index 301f043..bfeeff7 100644
--- a/libdimension/progress.c
+++ b/libdimension/progress.c
@@ -178,7 +178,9 @@ void
dmnsn_wait_progress(const dmnsn_progress *progress, double prog)
{
if (pthread_mutex_lock(progress->mutex) != 0) {
- dmnsn_error(DMNSN_SEVERITY_LOW, "Couldn't lock condition mutex.");
+ dmnsn_error(DMNSN_SEVERITY_MEDIUM, "Couldn't lock condition mutex.");
+ /* Busy-wait if we can't use the condition variable */
+ while (dmnsn_get_progress(progress) < prog);
} else {
while (dmnsn_get_progress(progress) < prog) {
if (pthread_cond_wait(progress->cond, progress->mutex) != 0) {
@@ -188,7 +190,7 @@ dmnsn_wait_progress(const dmnsn_progress *progress, double prog)
}
if (pthread_mutex_unlock(progress->mutex) != 0) {
- dmnsn_error(DMNSN_SEVERITY_LOW, "Couldn't unlock condition mutex.");
+ dmnsn_error(DMNSN_SEVERITY_MEDIUM, "Couldn't unlock condition mutex.");
}
}
}
@@ -198,7 +200,9 @@ void
dmnsn_new_progress_element(dmnsn_progress *progress, unsigned int total)
{
dmnsn_progress_element element = { .progress = 0, .total = total };
- dmnsn_array_push(progress->elements, &element);
+ dmnsn_progress_wrlock(progress);
+ dmnsn_array_push(progress->elements, &element);
+ dmnsn_progress_unlock(progress);
}
/* Only the innermost loop needs to call this function - it handles the rest
@@ -221,11 +225,17 @@ dmnsn_increment_progress(dmnsn_progress *progress)
element = dmnsn_array_at(progress->elements, size - 1);
++element->progress; /* Increment the next element */
}
-
- if (pthread_cond_broadcast(progress->cond) != 0) {
- dmnsn_error(DMNSN_SEVERITY_MEDIUM, "Couldn't signal condition variable.");
- }
dmnsn_progress_unlock(progress);
+
+ if (pthread_mutex_lock(progress->mutex) != 0) {
+ dmnsn_error(DMNSN_SEVERITY_MEDIUM, "Couldn't lock condition mutex.");
+ }
+ if (pthread_cond_broadcast(progress->cond) != 0) {
+ dmnsn_error(DMNSN_SEVERITY_MEDIUM, "Couldn't signal condition variable.");
+ }
+ if (pthread_mutex_unlock(progress->mutex) != 0) {
+ dmnsn_error(DMNSN_SEVERITY_MEDIUM, "Couldn't unlock condition mutex.");
+ }
}
/* Immediately set to 100% completion */
@@ -238,11 +248,17 @@ dmnsn_done_progress(dmnsn_progress *progress)
dmnsn_array_resize(progress->elements, 1);
element = dmnsn_array_at(progress->elements, 0);
element->progress = element->total;
-
- if (pthread_cond_broadcast(progress->cond) != 0) {
- dmnsn_error(DMNSN_SEVERITY_MEDIUM, "Couldn't signal condition variable.");
- }
dmnsn_progress_unlock(progress);
+
+ if (pthread_mutex_lock(progress->mutex) != 0) {
+ dmnsn_error(DMNSN_SEVERITY_MEDIUM, "Couldn't lock condition mutex.");
+ }
+ if (pthread_cond_broadcast(progress->cond) != 0) {
+ dmnsn_error(DMNSN_SEVERITY_MEDIUM, "Couldn't signal condition variable.");
+ }
+ if (pthread_mutex_unlock(progress->mutex) != 0) {
+ dmnsn_error(DMNSN_SEVERITY_MEDIUM, "Couldn't unlock condition mutex.");
+ }
}
/* Thread synchronization */