diff --git a/fsl/utils/idle.py b/fsl/utils/idle.py
index c1184a31a758b685b476e843140a14ce0b284980..7c4c881063cd2b5c2611d1aac12e2c4335208225 100644
--- a/fsl/utils/idle.py
+++ b/fsl/utils/idle.py
@@ -391,27 +391,41 @@ def cancelIdle(taskName):
     _idleQueueDict[taskName].timeout = -1
 
 
-def block(secs, delta=0.01):
+def block(secs, delta=0.01, until=None):
     """Blocks for the specified number of seconds, yielding to the main ``wx``
     loop.
 
     If ``wx`` is not available, or a ``wx`` application is not running, this
     function is equivalent to ``time.sleep(secs)``.
 
+    If ``until`` is provided, this function will block until ``until``
+    returns ``True``, or ``secs`` have elapsed, whichever comes first.
+
     :arg secs:  Time in seconds to block
     :arg delta: Time in seconds to sleep between successive yields to ``wx``.
+    :arg until: Function which returns ``True`` or ``False``, and which
+                determins when calls to ``block`` will return.
     """
 
-    from fsl.utils.platform import platform as fslplatform
+    def defaultUntil():
+        return False
 
-    if not fslplatform.haveGui:
-        time.sleep(secs)
-    else:
-        import wx
-        start = time.time()
-        while (time.time() - start) < secs:
+    def tick():
+        if fslplatform.haveGui:
+            import wx
             wx.YieldIfNeeded()
-            time.sleep(delta)
+        time.sleep(delta)
+
+    if until is None:
+        until = defaultUntil
+
+    from fsl.utils.platform import platform as fslplatform
+
+    start = time.time()
+    while (time.time() - start) < secs:
+        tick()
+        if until():
+            break
 
 
 def idle(task, *args, **kwargs):