Mercurial > hg-stable
changeset 39339: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 | 57f9b3d91abc |
children | 6f38284b23f4 |
files | mercurial/localrepo.py |
diffstat | 1 files changed, 16 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/localrepo.py Sun Aug 05 13:13:06 2018 +0900 +++ b/mercurial/localrepo.py Wed Aug 22 20:52:36 2018 +0900 @@ -436,14 +436,6 @@ self.root = self.wvfs.base self.path = self.wvfs.join(".hg") self.origroot = path - # This is only used by context.workingctx.match in order to - # detect files in subrepos. - self.auditor = pathutil.pathauditor( - self.root, callback=self._checknested) - # This is only used by context.basectx.match in order to detect - # files in subrepos. - self.nofsauditor = pathutil.pathauditor( - self.root, callback=self._checknested, realfs=False, cached=True) self.baseui = baseui self.ui = baseui.copy() self.ui.copy = baseui.copy # prevent copying repo configuration @@ -709,6 +701,22 @@ def _writerequirements(self): scmutil.writerequires(self.vfs, self.requirements) + # Don't cache auditor/nofsauditor, or you'll end up with reference cycle: + # self -> auditor -> self._checknested -> self + + @property + def auditor(self): + # This is only used by context.workingctx.match in order to + # detect files in subrepos. + return pathutil.pathauditor(self.root, callback=self._checknested) + + @property + def nofsauditor(self): + # This is only used by context.basectx.match in order to detect + # files in subrepos. + return pathutil.pathauditor(self.root, callback=self._checknested, + realfs=False, cached=True) + def _checknested(self, path): """Determine if path is a legal nested repository.""" if not path.startswith(self.root):