Repeatedly copying until there are no new changes would produce a consistent image (if it terminates -- it requires the writing speed to the output device to be faster than the rate at which new data is being written to the input disk).
It may possible to stop earlier. The precise condition for producing a consistent image is as follows:
Let A[i] be the most recent modification time of block i, let B[i] be the modification time of block i at the time it was copied, and let C[i] be the time of the first modification to block i after it was copied (or infinity if the block hasn't been modified since it was copied).
We can stop if max(B) < min(C).
In detail, here is how to compute A, B, and C:
1. Initially, A[i] = B[i] = C[i] = 0.
2. When we are notified that block i has been altered, set A[i] to the modification timestamp. If C[i] == infinity, set C[i] to A[i].
3. When we copy block i, set B[i] to A[i] and set C[i] to infinity.