FileImage: make thread-safe

FileImage needs to be thread-safe because multiple
threads gets data from it when an incremental OTA
package is created.

Test: apply incremental OTA on cuttlefish
Bug: 113175337
Change-Id: I31637fce0fbd66f3fa6c5c478da09bae65a52229
diff --git a/tools/releasetools/blockimgdiff.py b/tools/releasetools/blockimgdiff.py
index 2e5f804..b23eef1 100644
--- a/tools/releasetools/blockimgdiff.py
+++ b/tools/releasetools/blockimgdiff.py
@@ -205,6 +205,8 @@
     self.clobbered_blocks = RangeSet()
     self.extended = RangeSet()
 
+    self.generator_lock = threading.Lock()
+
     self.hashtree_info = None
     if hashtree_info_generator:
       self.hashtree_info = hashtree_info_generator.Generate(self)
@@ -236,10 +238,13 @@
     self._file.close()
 
   def _GetRangeData(self, ranges):
-    for s, e in ranges:
-      self._file.seek(s * self.blocksize)
-      for _ in range(s, e):
-        yield self._file.read(self.blocksize)
+    # Use a lock to protect the generator so that we will not run two
+    # instances of this generator on the same object simultaneously.
+    with self.generator_lock:
+      for s, e in ranges:
+        self._file.seek(s * self.blocksize)
+        for _ in range(s, e):
+          yield self._file.read(self.blocksize)
 
   def RangeSha1(self, ranges):
     h = sha1()