diff options
author | Tavian Barnes <tavianator@gmail.com> | 2009-10-26 00:54:15 +0000 |
---|---|---|
committer | Tavian Barnes <tavianator@gmail.com> | 2009-10-26 00:54:15 +0000 |
commit | 0bb6bfe0b08eb9fc2ba62f64bdb21cb5b592c292 (patch) | |
tree | e7ef618a917290a530cc2faec586724ac0265a60 /libdimension/progress.c | |
parent | 75f20754030726569ac8cbc243628c18e523f3bb (diff) | |
download | dimension-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.c | 38 |
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 */ |