[PATCH 2 of 2 V2] debuglocks: allow setting a lock

Paul Morelle paul.morelle at octobus.net
Tue Nov 14 12:22:24 EST 2017


# HG changeset patch
# User Paul Morelle <paul.morelle at octobus.net>
# Date 1510497286 -3600
#      Sun Nov 12 15:34:46 2017 +0100
# Node ID 61cf7ffd84b89889cbf6bbc2af13cdd67ba2d9f9
# Parent  b26aa142783235cddc7c90f2425aac53fbb612da
# EXP-Topic debugsetlocks
# Available At https://bitbucket.org/octobus/mercurial-devel/
#              hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 61cf7ffd84b8
debuglocks: allow setting a lock

diff -r b26aa1427832 -r 61cf7ffd84b8 mercurial/debugcommands.py
--- a/mercurial/debugcommands.py	Sun Nov 12 15:34:19 2017 +0100
+++ b/mercurial/debugcommands.py	Sun Nov 12 15:34:46 2017 +0100
@@ -14,6 +14,7 @@
 import operator
 import os
 import random
+import signal
 import socket
 import ssl
 import string
@@ -1173,7 +1174,10 @@
 @command('debuglocks',
          [('L', 'force-lock', None, _('free the store lock (DANGEROUS)')),
           ('W', 'force-wlock', None,
-           _('free the working state lock (DANGEROUS)'))],
+           _('free the working state lock (DANGEROUS)')),
+          ('s', 'set-lock', None, _('set the store lock until stopped')),
+          ('S', 'set-wlock', None,
+           _('set the working state lock until stopped'))],
          _('[OPTION]...'))
 def debuglocks(ui, repo, **opts):
     """show or modify state of locks
@@ -1192,6 +1196,10 @@
     instance, on a shared filesystem). Removing locks may also be
     blocked by filesystem permissions.
 
+    Setting a lock will prevent other commands from changing the data.
+    The command will wait until an interruption (SIGINT, SIGTERM, ...) occurs.
+    The set locks are removed when the command exits.
+
     Returns 0 if no locks are held.
 
     """
@@ -1203,6 +1211,29 @@
     if opts.get(r'force_lock') or opts.get(r'force_wlock'):
         return 0
 
+    # Ensure that SIGINT wouldn't be ignored
+    # see https://unix.stackexchange.com/a/372580
+    if not pycompat.iswindows:
+        signal.signal(signal.SIGINT, signal.SIG_DFL)
+
+    locks = []
+    try:
+        if opts.get(r'set_wlock'):
+            try:
+                locks.append(repo.wlock(False))
+            except error.LockHeld:
+                raise error.Abort(_('wlock is already held'))
+        if opts.get(r'set_lock'):
+            try:
+                locks.append(repo.lock(False))
+            except error.LockHeld:
+                raise error.Abort(_('lock is already held'))
+        if len(locks):
+            while True:
+                time.sleep(60)
+    finally:
+        release(*locks)
+
     now = time.time()
     held = 0
 
diff -r b26aa1427832 -r 61cf7ffd84b8 tests/test-completion.t
--- a/tests/test-completion.t	Sun Nov 12 15:34:19 2017 +0100
+++ b/tests/test-completion.t	Sun Nov 12 15:34:46 2017 +0100
@@ -272,7 +272,7 @@
   debuginstall: template
   debugknown: 
   debuglabelcomplete: 
-  debuglocks: force-lock, force-wlock
+  debuglocks: force-lock, force-wlock, set-lock, set-wlock
   debugmergestate: 
   debugnamecomplete: 
   debugobsolete: flags, record-parents, rev, exclusive, index, delete, date, user, template
diff -r b26aa1427832 -r 61cf7ffd84b8 tests/test-debugcommands.t
--- a/tests/test-debugcommands.t	Sun Nov 12 15:34:19 2017 +0100
+++ b/tests/test-debugcommands.t	Sun Nov 12 15:34:46 2017 +0100
@@ -119,14 +119,7 @@
 
 * Test setting the lock
 
-  $ python <<EOF &
-  > from mercurial import hg, ui as uimod
-  > import time
-  > 
-  > repo = hg.repository(uimod.ui.load(), path='$(pwd)')
-  > with repo.lock(False):
-  >     time.sleep(1)
-  > EOF
+  $ hg debuglocks -s &
   $ sleep 0.5
 
   $ hg debuglocks
@@ -138,14 +131,7 @@
 
 * Test setting the wlock
 
-  $ python <<EOF &
-  > from mercurial import hg, ui as uimod
-  > import time
-  > 
-  > repo = hg.repository(uimod.ui.load(), path='$(pwd)')
-  > with repo.wlock(False):
-  >     time.sleep(1)
-  > EOF
+  $ hg debuglocks -S &
   $ sleep 0.5
 
   $ hg debuglocks
@@ -157,21 +143,24 @@
 
 * Test setting both locks
 
-  $ python <<EOF &
-  > from mercurial import hg, ui as uimod
-  > import time
-  > 
-  > repo = hg.repository(uimod.ui.load(), path='$(pwd)')
-  > with repo.wlock(False):
-  >     with repo.lock(False):
-  >         time.sleep(1)
-  > EOF
+  $ hg debuglocks -Ss &
   $ sleep 0.5
 
   $ hg debuglocks
   lock:  user *, process *, host * (*s) (glob)
   wlock: user *, process *, host * (*s) (glob)
   [2]
+
+* Test failing to set a lock
+
+  $ hg debuglocks -s
+  abort: lock is already held
+  [255]
+
+  $ hg debuglocks -S
+  abort: wlock is already held
+  [255]
+
   $ kill -INT %1
   $ wait
 
@@ -181,14 +170,7 @@
 
 * Test forcing the lock
 
-  $ python <<EOF &
-  > from mercurial import hg, ui as uimod
-  > import time
-  > 
-  > repo = hg.repository(uimod.ui.load(), path='$(pwd)')
-  > with repo.lock(False):
-  >     time.sleep(1)
-  > EOF
+  $ hg debuglocks -s &
   $ sleep 0.5
 
   $ hg debuglocks
@@ -207,14 +189,7 @@
 
 * Test forcing the wlock
 
-  $ python <<EOF &
-  > from mercurial import hg, ui as uimod
-  > import time
-  > 
-  > repo = hg.repository(uimod.ui.load(), path='$(pwd)')
-  > with repo.wlock(False):
-  >     time.sleep(1)
-  > EOF
+  $ hg debuglocks -S &
   $ sleep 0.5
 
   $ hg debuglocks


More information about the Mercurial-devel mailing list