From c0284b69fe0ee82d1f604a1b6f0511b4f129b919 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Fri, 19 Aug 2011 00:05:22 -0600 Subject: Support thread cancelation, and handle ^C in the client. --- libdimension/progress.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'libdimension/progress.c') 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); -- cgit v1.2.3