-
Notifications
You must be signed in to change notification settings - Fork 608
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(ImageBuf): make IB::Iterator lazy in its making the image writab…
…le (#4033) Historically, ImageBuf has provided Iterator for writing to mutable IB's and ConstIterator for reading into IBs. If you initialized an Iterator to an IB that was ImageCache-backed (and therefore by definition not mutable), it would convert the IB to the mutable kind (basically by allocating the memory and reading the file through the IC, thus freeing the IB of its dependence on the cache. An important bug was fixed by PR 3997, which kinda proved that people were not depending on this behavior, since it would tend to fail. But it also got me thinking about to what degree the whole Iterator vs ConstIterator was really necessary, or did it just make things harder for users. In this proposed patch, we change the Iterator behavior so that instead of immediately making the IB writable as soon as the Iterator was instantiated and associated with the IB, we instead treat it as a ConstIterator UNTIL it actually tries to write a value, at which point we ensure that the IB is writable. The bottom line is that this seems to work. If you don't want to have to think about Iterator vs ConstIterator, you don't have to. Iterator is fine. If you don't actually write into any of the pixels, it behaves just like a ConstIterator, including being perfectly happy with an IC-backed IB. Performance metrics indicate that there is NO penalty for doing so -- if you are only reading pixel values, traversing an IB with Iterator is the same speed as doing it with ConstIterator. I had one sleepless night after implementing this when suddenly I realized that this was totally not thread-safe, that somehow multiple iterators traversing the same IB would screw each other up if one of them wrote to a pixel and converted the image. So I put in a test to have many threads concurrently traversing the same IB, some with ConstIterator, some with Iterator but only reading, and some with Iterator and writing. I have not been able to trigger any failures or crashes. It seems fine. (I did use the mutex a little more aggressively than before.) Why is this not as dangerous as I thought? Mainly because once an iterator (of either variety) thinks it's dealing with an IC-backed ImageBuf, basically, it will just happily keep using the IC all on its own, even if the IB that it's supposedly traversing has, because another thread's iterator has written to a pixel, "localized" the image and severed the IC dependence. Then if it also needs to write, it will (safely, because of a mutex) see that the image is already localized/writable, and start using that representation. So herein lies a very important caveat about using IB iterators: If you have multiple iterators traversing the same IB and any of them are *writing* to the image, the iterators may not see a globally temporally consistent version of the image. Put in plain English: iterators that are strictly reading may see an IC-backed disk image as it was on disk, and not as it has since been modified by a different active iterator. So if you are modifying an image in place, beware of using multiple iterators, because a reading iterator may or may not see the changes that a writing iterator made to a pixel value. Signed-off-by: Larry Gritz <[email protected]>
- Loading branch information
Showing
3 changed files
with
178 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters