# HG changeset patch # User Durham Goode # Date 1395789007 25200 # Node ID 47d43e2323c5f8c6492d8ce01117424c716ceaea # Parent 5d57b2101ab119bce762025b8d83a00db7263e3b revset: fix generatorset race condition If two things were iterating over a generatorset at the same time, they could miss out on the things the other was generating, resulting in incomplete results. This fixes it by making it possible for two things to iterate at once, by always checking the _genlist at the beginning of each iteration. I was only able to repro it with pending changes from my other commits, but they aren't ready yet. So I'm unable to add a test for now. diff -r 5d57b2101ab1 -r 47d43e2323c5 mercurial/revset.py --- a/mercurial/revset.py Tue Mar 25 23:07:52 2014 +0100 +++ b/mercurial/revset.py Tue Mar 25 16:10:07 2014 -0700 @@ -2624,10 +2624,8 @@ gen: a generator producing the values for the generatorset. """ self._gen = gen - self._iter = iter(gen) self._cache = {} self._genlist = baseset([]) - self._iterated = False self._finished = False def __contains__(self, x): @@ -2639,28 +2637,30 @@ if l == x: return True - self._finished = True self._cache[x] = False return False def __iter__(self): - if self._iterated: - # At least a part of the list should be cached if iteration has - # started over the generatorset. - for l in self._genlist: - yield l - - for item in self._consumegen(): - yield item + if self._finished: + for x in self._genlist: + yield x + return + + i = 0 + genlist = self._genlist + consume = self._consumegen() + while True: + if i < len(genlist): + yield genlist[i] + else: + yield consume.next() + i += 1 def _consumegen(self): - self._iterated = True - for item in self._gen: self._cache[item] = True self._genlist.append(item) yield item - self._finished = True def set(self):