sapling/tests/progresstest.py
Mark Thomas f1ebfba3dc progress: deactivate the progress thread when shutting down
Summary:
The progress bar thread is a daemon thread, so that it doesn't need to be
deactivated manually.  However, this means the thread terminates and the lock
is released during interpreter shutdown.  Because Python clears module
attributes at the start of interpreter shutdown (see [1]), releasing the lock
fails as it can no longer get the thread identity.

To mitigate this, we register an atexit handler to terminate and join to the
progress bar thread.

[1] https://stackoverflow.com/questions/25649676/where-is-pythons-shutdown-procedure-documented

Differential Revision: D7568155

fbshipit-source-id: 85ef10af6c1576d5beceb78f8514e0e440cdab7f
2018-04-13 21:51:51 -07:00

90 lines
2.7 KiB
Python

from __future__ import absolute_import
import time
from mercurial import (
progress,
registrar,
util,
)
cmdtable = {}
command = registrar.command(cmdtable)
class faketime(object):
def __init__(self):
self.now = 0
def time(self):
return self.now
def increment(self):
now = self.now
self.now += 1
return now
_faketime = faketime()
time.time = _faketime.time
unicodeloopitems = [
u'\u3042\u3044'.encode('utf-8'), # 2 x 2 = 4 columns
u'\u3042\u3044\u3046'.encode('utf-8'), # 2 x 3 = 6 columns
u'\u3042\u3044\u3046\u3048'.encode('utf-8'), # 2 x 4 = 8 columns
]
@command('progresstest',
[('', 'nested', False, 'show nested results'),
('', 'unicode', False, 'use unicode topics and items'),
('', 'output', False, 'output text on each iteration')],
'hg progresstest loops total', norepo=True)
def progresstest(ui, loops, total, **opts):
loops = int(loops)
total = int(total)
if total == -1:
total = None
nested = opts.get('nested', None)
useunicode = opts.get('unicode', False)
if useunicode:
topic = u'\u3042\u3044\u3046\u3048'.encode('utf-8')
else:
topic = 'progress test'
with progress.bar(ui, topic, 'cycles', total) as prog:
for i in range(loops + 1):
if useunicode:
prog.value = (i, unicodeloopitems[i % len(unicodeloopitems)])
else:
prog.value = (i, 'loop %s' % i)
progress._engine.pump(_faketime.increment())
if nested:
nestedtotal = 5 if i % 6 == 5 else 2
with progress.bar(ui, 'nested progress',
total=nestedtotal) as nestedprog:
for j in range(nestedtotal + 1):
nestedprog.value = (j, 'nest %s' % j)
progress._engine.pump(_faketime.increment())
@command('bytesprogresstest', norepo=True)
def bytesprogresstest(ui):
values = [0, 10, 250, 999, 1000, 1024, 22000, 1048576,
1474560, 123456789, 555555555, 1000000000, 1111111111]
with progress.bar(ui, 'bytes progress test', 'bytes', max(values),
formatfunc=util.bytecount) as prog:
for value in values:
prog.value = (value, '%s bytes' % value)
progress._engine.pump(_faketime.increment())
def uisetup(ui):
class syncengine(progress._engine.__class__):
def _activate(self, ui):
pass
def _deactivate(self):
pass
def pump(self, now):
self._recalculatedisplay(now)
self._updateestimation(now)
self._show(now)
progress._engine.__class__ = syncengine