diff options
Diffstat (limited to 'libdimension/progress.c')
-rw-r--r-- | libdimension/progress.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/libdimension/progress.c b/libdimension/progress.c index 17fa7dc..0fa1c66 100644 --- a/libdimension/progress.c +++ b/libdimension/progress.c @@ -60,9 +60,8 @@ dmnsn_finish_progress(dmnsn_progress *progress) if (progress) { /* Get the thread's return value */ - if (pthread_join(progress->thread, &ptr) != 0) { - dmnsn_error("Joining worker thread failed."); - } else if (ptr) { + dmnsn_join_thread(progress->thread, &ptr); + if (ptr && ptr != PTHREAD_CANCELED) { retval = *(int *)ptr; dmnsn_free(ptr); } @@ -86,6 +85,13 @@ dmnsn_finish_progress(dmnsn_progress *progress) return retval; } +/* Cancel a background thread */ +void +dmnsn_cancel_progress(dmnsn_progress *progress) +{ + pthread_cancel(progress->thread); +} + /* Get the current progress of the worker thread, in [0.0, 1.0] */ double dmnsn_get_progress(const dmnsn_progress *progress) @@ -127,6 +133,11 @@ dmnsn_set_progress_total(dmnsn_progress *progress, size_t total) void dmnsn_increment_progress(dmnsn_progress *progress) { + /* Allow a thread to be canceled whenever it increments a progress object -- + this is close to PTHREAD_CANCEL_ASYNCHRONOUS but allows consistent state + on cancellation */ + pthread_testcancel(); + dmnsn_write_lock(progress->rwlock); ++progress->progress; dmnsn_unlock_rwlock(progress->rwlock); |