comparison mercurial/localrepo.py @ 26499:e72b62b154b0

localrepo: prevent wlock from being inherited when a transaction is running Review feedback from Pierre-Yves David. A separate line of work is working to ensure that dirstate writes are written to a separate 'pending' file while a transaction is active. Lock inheritance currently conflicts with that, so dodge the issue by simply preventing inheritance while a transaction is running. Custom merge drivers aren't going to run inside a transaction, so this doesn't affect that.
author Siddharth Agarwal <sid0@fb.com>
date Tue, 06 Oct 2015 13:19:05 -0700
parents 2a3fc0272e3f
children 8f2ff40fe9c9
comparison
equal deleted inserted replaced
26498:e8564e04382d 26499:e72b62b154b0
1210 if k == 'dirstate' or k not in self.__dict__: 1210 if k == 'dirstate' or k not in self.__dict__:
1211 continue 1211 continue
1212 ce.refresh() 1212 ce.refresh()
1213 1213
1214 def _lock(self, vfs, lockname, wait, releasefn, acquirefn, desc, 1214 def _lock(self, vfs, lockname, wait, releasefn, acquirefn, desc,
1215 parentenvvar=None): 1215 inheritchecker=None, parentenvvar=None):
1216 parentlock = None 1216 parentlock = None
1217 # the contents of parentenvvar are used by the underlying lock to 1217 # the contents of parentenvvar are used by the underlying lock to
1218 # determine whether it can be inherited 1218 # determine whether it can be inherited
1219 if parentenvvar is not None: 1219 if parentenvvar is not None:
1220 parentlock = os.environ.get(parentenvvar) 1220 parentlock = os.environ.get(parentenvvar)
1221 try: 1221 try:
1222 l = lockmod.lock(vfs, lockname, 0, releasefn=releasefn, 1222 l = lockmod.lock(vfs, lockname, 0, releasefn=releasefn,
1223 acquirefn=acquirefn, desc=desc, 1223 acquirefn=acquirefn, desc=desc,
1224 inheritchecker=inheritchecker,
1224 parentlock=parentlock) 1225 parentlock=parentlock)
1225 except error.LockHeld as inst: 1226 except error.LockHeld as inst:
1226 if not wait: 1227 if not wait:
1227 raise 1228 raise
1228 self.ui.warn(_("waiting for lock on %s held by %r\n") % 1229 self.ui.warn(_("waiting for lock on %s held by %r\n") %
1263 l = self._lock(self.svfs, "lock", wait, None, 1264 l = self._lock(self.svfs, "lock", wait, None,
1264 self.invalidate, _('repository %s') % self.origroot) 1265 self.invalidate, _('repository %s') % self.origroot)
1265 self._lockref = weakref.ref(l) 1266 self._lockref = weakref.ref(l)
1266 return l 1267 return l
1267 1268
1269 def _wlockchecktransaction(self):
1270 if self.currenttransaction() is not None:
1271 raise error.LockInheritanceContractViolation(
1272 'wlock cannot be inherited in the middle of a transaction')
1273
1268 def wlock(self, wait=True): 1274 def wlock(self, wait=True):
1269 '''Lock the non-store parts of the repository (everything under 1275 '''Lock the non-store parts of the repository (everything under
1270 .hg except .hg/store) and return a weak reference to the lock. 1276 .hg except .hg/store) and return a weak reference to the lock.
1271 1277
1272 Use this before modifying files in .hg. 1278 Use this before modifying files in .hg.
1294 1300
1295 self._filecache['dirstate'].refresh() 1301 self._filecache['dirstate'].refresh()
1296 1302
1297 l = self._lock(self.vfs, "wlock", wait, unlock, 1303 l = self._lock(self.vfs, "wlock", wait, unlock,
1298 self.invalidatedirstate, _('working directory of %s') % 1304 self.invalidatedirstate, _('working directory of %s') %
1299 self.origroot, parentenvvar='HG_WLOCK_LOCKER') 1305 self.origroot,
1306 inheritchecker=self._wlockchecktransaction,
1307 parentenvvar='HG_WLOCK_LOCKER')
1300 self._wlockref = weakref.ref(l) 1308 self._wlockref = weakref.ref(l)
1301 return l 1309 return l
1302 1310
1303 def _currentlock(self, lockref): 1311 def _currentlock(self, lockref):
1304 """Returns the lock if it's held, or None if it's not.""" 1312 """Returns the lock if it's held, or None if it's not."""