From 12c4a5eb07f346083a59bc7d18567b2df3ed94ee Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Sat, 26 Apr 2014 15:08:09 -0400 Subject: future: Add a dmnsn_future_is_done() function. --- dimension/preview.py | 2 +- libdimension-python/dimension.pxd | 1 + libdimension-python/dimension.pyx | 3 +++ libdimension/dimension/future.h | 7 +++++++ libdimension/future-internal.h | 4 ++-- libdimension/future.c | 22 ++++++++++++++++++---- libdimension/tests/render.c | 2 +- libdimension/threads.c | 4 ++-- 8 files changed, 35 insertions(+), 10 deletions(-) diff --git a/dimension/preview.py b/dimension/preview.py index bc8e105..e4e9c80 100644 --- a/dimension/preview.py +++ b/dimension/preview.py @@ -58,7 +58,7 @@ class PreviewWindow(QtGui.QMainWindow): @QtCore.pyqtSlot() def update_preview(self): self.widget.updateGL() - if self.future.progress() == 1: + if self.future.is_done(): self.render_timer.stop() self.close_timer = QtCore.QTimer(self) self.close_timer.singleShot(1000, self.close) diff --git a/libdimension-python/dimension.pxd b/libdimension-python/dimension.pxd index 4df0786..fb02fbd 100644 --- a/libdimension-python/dimension.pxd +++ b/libdimension-python/dimension.pxd @@ -72,6 +72,7 @@ cdef extern from "../libdimension/dimension.h": int dmnsn_future_join(dmnsn_future *future) nogil void dmnsn_future_cancel(dmnsn_future *future) double dmnsn_future_progress(dmnsn_future *future) + bint dmnsn_future_is_done(dmnsn_future *future) void dmnsn_future_wait(dmnsn_future *future, double progress) nogil void dmnsn_future_pause(dmnsn_future *future) nogil void dmnsn_future_resume(dmnsn_future *future) diff --git a/libdimension-python/dimension.pyx b/libdimension-python/dimension.pyx index 7b6619f..98fc41d 100644 --- a/libdimension-python/dimension.pyx +++ b/libdimension-python/dimension.pyx @@ -85,6 +85,9 @@ cdef class Future: def progress(self): self._assert_unfinished() return dmnsn_future_progress(self._future) + def is_done(self): + self._assert_unfinished() + return dmnsn_future_is_done(self._future) def wait(self, double progress): self._assert_unfinished() diff --git a/libdimension/dimension/future.h b/libdimension/dimension/future.h index 9f1f14a..9ba28b1 100644 --- a/libdimension/dimension/future.h +++ b/libdimension/dimension/future.h @@ -50,6 +50,13 @@ void dmnsn_future_cancel(dmnsn_future *future); */ double dmnsn_future_progress(const dmnsn_future *future); +/** + * Find out if a background task is finished. + * @param[in] future The background task to examine. + * @return true if the task is done, false otherwise. + */ +bool dmnsn_future_is_done(const dmnsn_future *future); + /** * Wait for a certain amount of progress. Always use this rather than * spinlocking. diff --git a/libdimension/future-internal.h b/libdimension/future-internal.h index 644a486..5fcd553 100644 --- a/libdimension/future-internal.h +++ b/libdimension/future-internal.h @@ -33,12 +33,12 @@ DMNSN_INTERNAL void dmnsn_future_set_total(dmnsn_future *future, size_t total); /** Increment the progress of a background task. */ DMNSN_INTERNAL void dmnsn_future_increment(dmnsn_future *future); /** Instantly complete the background teask. */ -DMNSN_INTERNAL void dmnsn_future_done(dmnsn_future *future); +DMNSN_INTERNAL void dmnsn_future_finish(dmnsn_future *future); /** Set the number of worker threads. */ DMNSN_INTERNAL void dmnsn_future_set_nthreads(dmnsn_future *future, unsigned int nthreads); /** Notify completion of a worker thread. */ -DMNSN_INTERNAL void dmnsn_future_thread_done(dmnsn_future *future); +DMNSN_INTERNAL void dmnsn_future_finish_thread(dmnsn_future *future); struct dmnsn_future { size_t progress; /**< Completed loop iterations. */ diff --git a/libdimension/future.c b/libdimension/future.c index 8d9c0c8..622d40e 100644 --- a/libdimension/future.c +++ b/libdimension/future.c @@ -114,6 +114,20 @@ dmnsn_future_progress(const dmnsn_future *future) return progress; } +/* Find out whether the task is complete. */ +bool +dmnsn_future_is_done(const dmnsn_future *future) +{ + dmnsn_future *mfuture = MUTATE(future); + bool result; + + dmnsn_lock_mutex(&mfuture->mutex); + result = future->progress == future->total; + dmnsn_unlock_mutex(&mfuture->mutex); + + return result; +} + /* Wait until dmnsn_future_progress(future) >= progress */ void dmnsn_future_wait(const dmnsn_future *future, double progress) @@ -217,7 +231,7 @@ dmnsn_future_increment(dmnsn_future *future) /* Immediately set to 100% completion */ void -dmnsn_future_done(dmnsn_future *future) +dmnsn_future_finish(dmnsn_future *future) { dmnsn_lock_mutex(&future->mutex); future->progress = future->total; @@ -241,15 +255,15 @@ dmnsn_future_set_nthreads(dmnsn_future *future, unsigned int nthreads) /* Notify completion of a worker thread */ void -dmnsn_future_thread_done(dmnsn_future *future) +dmnsn_future_finish_thread(dmnsn_future *future) { dmnsn_lock_mutex(&future->mutex); dmnsn_assert(future->nthreads > 0, - "dmnsn_future_thread_done() called with no threads"); + "dmnsn_future_finish_thread() called with no threads"); --future->nthreads; dmnsn_assert(future->nrunning > 0, - "dmnsn_future_thread_done() called with no running threads"); + "dmnsn_future_finish_thread() called with no running threads"); if (--future->nrunning == 0) { dmnsn_cond_broadcast(&future->none_running_cond); } diff --git a/libdimension/tests/render.c b/libdimension/tests/render.c index 1efff28..0192d35 100644 --- a/libdimension/tests/render.c +++ b/libdimension/tests/render.c @@ -366,7 +366,7 @@ main(void) /* Display the scene as it's rendered */ if (display) { - while (dmnsn_future_progress(future) < 1.0) { + while (!dmnsn_future_is_done(future)) { dmnsn_future_pause(future); if (dmnsn_gl_write_canvas(scene->canvas) != 0) { dmnsn_delete_display(display); diff --git a/libdimension/threads.c b/libdimension/threads.c index 76f4796..85832b9 100644 --- a/libdimension/threads.c +++ b/libdimension/threads.c @@ -41,7 +41,7 @@ dmnsn_thread_cleanup(void *arg) dmnsn_future *future = payload->future; dmnsn_free(payload); - dmnsn_future_done(future); + dmnsn_future_finish(future); } /** pthread callback -- call the real thread callback. */ @@ -88,7 +88,7 @@ dmnsn_concurrent_thread(void *ptr) payload->ret = payload->ccthread_fn(payload->arg, payload->thread, payload->nthreads); if (payload->future) { - dmnsn_future_thread_done(payload->future); + dmnsn_future_finish_thread(payload->future); } return NULL; } -- cgit v1.2.3