worker: stop relying on garbage collection to release memoryview
On CPython, before resizing the bytearray, all memoryviews referencing it must
be released. Before this change, we ensured that all references to them were
deleted. On CPython, this was enough to set the reference count to zero, which
results in garbage collecting and releasing them.
On PyPy, releasing the memoryviews is not necessary because they are implemented
differently. If it would be necessary however, ensuring that all references are
deleted would not be suffient because PyPy doesn’t use reference counting.
By using with statements that take care of releasing the memoryviews, we ensure
that the bytearray is resizable without relying on implementation details. So
while this doesn’t fix any observable bug, it increases compatiblity with other
and future Python implementations.
# Support code for event tracing in Mercurial. Lives in demandimport
# so it can also be used in demandimport.
#
# Copyright 2018 Google LLC.
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
import contextlib
import os
_pipe = None
_checked = False
_session = 'none'
def _isactive():
global _pipe, _session, _checked
if _pipe is None:
if _checked:
return False
_checked = True
if 'HGCATAPULTSERVERPIPE' not in os.environ:
return False
_pipe = open(os.environ['HGCATAPULTSERVERPIPE'], 'w', 1)
_session = os.environ.get('HGCATAPULTSESSION', 'none')
return True
@contextlib.contextmanager
def log(whencefmt, *whenceargs):
if not _isactive():
yield
return
whence = whencefmt % whenceargs
try:
# Both writes to the pipe are wrapped in try/except to ignore
# errors, as we can see mysterious errors in here if the pager
# is active. Presumably other conditions could trigger
# problems too.
try:
_pipe.write('START %s %s\n' % (_session, whence))
except IOError:
pass
yield
finally:
try:
_pipe.write('END %s %s\n' % (_session, whence))
except IOError:
pass
def counter(label, amount, *labelargs):
if not _isactive():
return
l = label % labelargs
# See above in log() for why this is in a try/except.
try:
_pipe.write('COUNTER %s %d %s\n' % (_session, amount, l))
except IOError:
pass