Mercurial > hg
view mercurial/pushkey.py @ 48038:52018f8ef020 stable
persistent-nodemap: introduce a test to highlight possible race
Weakness in the current file caching of the changelog means that a writer can
end up using an outdated docket. This might result in "committed"
persistent-nodemap data from a previous writer to be overwritten by a later
writer. This break the strong "append only" assumption of the persistent nodemap
and can result in confused reader.
The race windows are quite narrow. See the test documentation for details.
The issues is fixed in the next changeset.
Differential Revision: https://phab.mercurial-scm.org/D11481
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Tue, 21 Sep 2021 21:18:50 +0200 |
parents | d4ba4d51f85f |
children | 6000f5b25c9b |
line wrap: on
line source
# pushkey.py - dispatching for pushing and pulling keys # # Copyright 2010 Olivia Mackall <olivia@selenic.com> # # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. from __future__ import absolute_import from . import ( bookmarks, encoding, obsolete, phases, ) def _nslist(repo): n = {} for k in _namespaces: n[k] = b"" if not obsolete.isenabled(repo, obsolete.exchangeopt): n.pop(b'obsolete') return n _namespaces = { b"namespaces": (lambda *x: False, _nslist), b"bookmarks": (bookmarks.pushbookmark, bookmarks.listbookmarks), b"phases": (phases.pushphase, phases.listphases), b"obsolete": (obsolete.pushmarker, obsolete.listmarkers), } def register(namespace, pushkey, listkeys): _namespaces[namespace] = (pushkey, listkeys) def _get(namespace): return _namespaces.get(namespace, (lambda *x: False, lambda *x: {})) def push(repo, namespace, key, old, new): '''should succeed iff value was old''' pk = _get(namespace)[0] return pk(repo, key, old, new) def list(repo, namespace): '''return a dict''' lk = _get(namespace)[1] return lk(repo) encode = encoding.fromlocal decode = encoding.tolocal def encodekeys(keys): """encode the content of a pushkey namespace for exchange over the wire""" return b'\n'.join([b'%s\t%s' % (encode(k), encode(v)) for k, v in keys]) def decodekeys(data): """decode the content of a pushkey namespace from exchange over the wire""" result = {} for l in data.splitlines(): k, v = l.split(b'\t') result[decode(k)] = decode(v) return result