diff options
-rw-r--r-- | dimension/preview.py | 2 | ||||
-rw-r--r-- | libdimension-python/dimension.pxd | 1 | ||||
-rw-r--r-- | libdimension-python/dimension.pyx | 3 | ||||
-rw-r--r-- | libdimension/dimension/future.h | 7 | ||||
-rw-r--r-- | libdimension/future-internal.h | 4 | ||||
-rw-r--r-- | libdimension/future.c | 22 | ||||
-rw-r--r-- | libdimension/tests/render.c | 2 | ||||
-rw-r--r-- | 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 @@ -51,6 +51,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. * @param[in] future The background task to monitor. 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; } |