comparison mercurial/localrepo.py @ 39312:9198e41df6ef

localrepo: do not cache auditor/nofsauditor which would make reference cycle Before, self.auditor and self.nofsauditor held self through self._checknested, and the following code couldn't free a repo by ref-counting. def main(): repo = localrepo.localrepository(uimod.ui(), '../testrepos/hello') main() With this change, the cache of the nofsauditor is limited to a single match session. I think that's okay as the nofsauditor doesn't do any filesystem access. Alternatively, maybe we can remove the callback from nofsauditor since it isn't used unless realfs=True, but I have no idea whether it is a bug or not.
author Yuya Nishihara <yuya@tcha.org>
date Wed, 22 Aug 2018 20:52:36 +0900
parents 5763216ba311
children b66ea3fc3a86
comparison
equal deleted inserted replaced
39311:57f9b3d91abc 39312:9198e41df6ef
434 # repository's .hg/store directory. 434 # repository's .hg/store directory.
435 self.svfs = None 435 self.svfs = None
436 self.root = self.wvfs.base 436 self.root = self.wvfs.base
437 self.path = self.wvfs.join(".hg") 437 self.path = self.wvfs.join(".hg")
438 self.origroot = path 438 self.origroot = path
439 # This is only used by context.workingctx.match in order to
440 # detect files in subrepos.
441 self.auditor = pathutil.pathauditor(
442 self.root, callback=self._checknested)
443 # This is only used by context.basectx.match in order to detect
444 # files in subrepos.
445 self.nofsauditor = pathutil.pathauditor(
446 self.root, callback=self._checknested, realfs=False, cached=True)
447 self.baseui = baseui 439 self.baseui = baseui
448 self.ui = baseui.copy() 440 self.ui = baseui.copy()
449 self.ui.copy = baseui.copy # prevent copying repo configuration 441 self.ui.copy = baseui.copy # prevent copying repo configuration
450 self.vfs = vfsmod.vfs(self.path, cacheaudited=True) 442 self.vfs = vfsmod.vfs(self.path, cacheaudited=True)
451 if (self.ui.configbool('devel', 'all-warnings') or 443 if (self.ui.configbool('devel', 'all-warnings') or
706 if REVLOGV2_REQUIREMENT in self.requirements: 698 if REVLOGV2_REQUIREMENT in self.requirements:
707 self.svfs.options['revlogv2'] = True 699 self.svfs.options['revlogv2'] = True
708 700
709 def _writerequirements(self): 701 def _writerequirements(self):
710 scmutil.writerequires(self.vfs, self.requirements) 702 scmutil.writerequires(self.vfs, self.requirements)
703
704 # Don't cache auditor/nofsauditor, or you'll end up with reference cycle:
705 # self -> auditor -> self._checknested -> self
706
707 @property
708 def auditor(self):
709 # This is only used by context.workingctx.match in order to
710 # detect files in subrepos.
711 return pathutil.pathauditor(self.root, callback=self._checknested)
712
713 @property
714 def nofsauditor(self):
715 # This is only used by context.basectx.match in order to detect
716 # files in subrepos.
717 return pathutil.pathauditor(self.root, callback=self._checknested,
718 realfs=False, cached=True)
711 719
712 def _checknested(self, path): 720 def _checknested(self, path):
713 """Determine if path is a legal nested repository.""" 721 """Determine if path is a legal nested repository."""
714 if not path.startswith(self.root): 722 if not path.startswith(self.root):
715 return False 723 return False