From 0521236fdc901e6ccdd5f34def4ea58d8d4e608b Mon Sep 17 00:00:00 2001 From: Jun Wu Date: Fri, 28 Sep 2018 16:46:41 -0700 Subject: [PATCH] hgsql: move lock order check to sql locks Summary: The lock check should be making sure local repo lock is taken before the SQL lock. The current code does not work well. One of the reasons is because repo locks can be nested. Clean up the lock check so we now check at SQL lock functions to make sure we still have the repo lock held. This way we don't have to replace the repo lock functions. It is not working yet because there are other code paths to fix. Reviewed By: phillco Differential Revision: D10108593 fbshipit-source-id: 489e4f27c06671191cf2084c7a726381be24a81f --- hgext/hgsql.py | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/hgext/hgsql.py b/hgext/hgsql.py index 1c90ad279b..9617f04e35 100644 --- a/hgext/hgsql.py +++ b/hgext/hgsql.py @@ -717,6 +717,7 @@ def wraprepo(repo): self.heldlocks.add(name) def sqlwritelock(self, trysync=False): + self._enforcelocallocktaken() self._sqllock(writelock, trysync) def _hassqllock(self, name, checkserver=True): @@ -753,25 +754,17 @@ def wraprepo(repo): self.sqlpostrelease = [] def sqlwriteunlock(self): - repo._sqlunlock(writelock) + self._enforcelocallocktaken() + self._sqlunlock(writelock) - def lock(self, *args, **kwargs): - wl = self._wlockref and self._wlockref() - if ( - not self._issyncing - and not (wl is not None and wl.held) - and not self.hassqlwritelock(checkserver=False) - ): - self._recordbadlockorder() - return super(sqllocalrepo, self).lock(*args, **kwargs) - - def wlock(self, *args, **kwargs): - if not self._issyncing and not self.hassqlwritelock(checkserver=False): - self._recordbadlockorder() - return super(sqllocalrepo, self).wlock(*args, **kwargs) - - def _recordbadlockorder(self): - self.ui.debug("invalid lock order\n") + def _enforcelocallocktaken(self): + if not getattr(self, "_checklockorder", False): + return + if self._issyncing: + return + if self._currentlock(self._lockref): + return + raise error.ProgrammingError("invalid lock order") def transaction(self, *args, **kwargs): tr = super(sqllocalrepo, self).transaction(*args, **kwargs)