Mercurial > hg
comparison mercurial/exchange.py @ 24752:5640efd1b160
unbundle: acquire 'wlock' when processing bundle2 (BC) (issue4596)
A bundle2 may contain bookmark updates (or other extension content) that
requires the 'wlock' to be written. As 'wlock' must be acquired before 'lock',
we must stay on the side of caution and use both in all case to ensure their
ordering.
author | Pierre-Yves David <pierre-yves.david@fb.com> |
---|---|
date | Wed, 15 Apr 2015 01:16:40 -0400 |
parents | 457e26da029b |
children | 5dc5cd7abbf5 |
comparison
equal
deleted
inserted
replaced
24751:dc4daf028f9c | 24752:5640efd1b160 |
---|---|
8 from i18n import _ | 8 from i18n import _ |
9 from node import hex, nullid | 9 from node import hex, nullid |
10 import errno, urllib | 10 import errno, urllib |
11 import util, scmutil, changegroup, base85, error | 11 import util, scmutil, changegroup, base85, error |
12 import discovery, phases, obsolete, bookmarks as bookmod, bundle2, pushkey | 12 import discovery, phases, obsolete, bookmarks as bookmod, bundle2, pushkey |
13 import lock as lockmod | |
13 | 14 |
14 def readbundle(ui, fh, fname, vfs=None): | 15 def readbundle(ui, fh, fname, vfs=None): |
15 header = changegroup.readexactly(fh, 4) | 16 header = changegroup.readexactly(fh, 4) |
16 | 17 |
17 alg = None | 18 alg = None |
1273 bundle and its application. | 1274 bundle and its application. |
1274 | 1275 |
1275 If the push was raced as PushRaced exception is raised.""" | 1276 If the push was raced as PushRaced exception is raised.""" |
1276 r = 0 | 1277 r = 0 |
1277 # need a transaction when processing a bundle2 stream | 1278 # need a transaction when processing a bundle2 stream |
1278 tr = None | 1279 wlock = lock = tr = None |
1279 lock = repo.lock() | |
1280 try: | 1280 try: |
1281 check_heads(repo, heads, 'uploading changes') | 1281 check_heads(repo, heads, 'uploading changes') |
1282 # push can proceed | 1282 # push can proceed |
1283 if util.safehasattr(cg, 'params'): | 1283 if util.safehasattr(cg, 'params'): |
1284 try: | 1284 try: |
1285 wlock = repo.wlock() | |
1286 lock = repo.lock() | |
1285 tr = repo.transaction(source) | 1287 tr = repo.transaction(source) |
1286 tr.hookargs['source'] = source | 1288 tr.hookargs['source'] = source |
1287 tr.hookargs['url'] = url | 1289 tr.hookargs['url'] = url |
1288 tr.hookargs['bundle2'] = '1' | 1290 tr.hookargs['bundle2'] = '1' |
1289 r = bundle2.processbundle(repo, cg, lambda: tr).reply | 1291 r = bundle2.processbundle(repo, cg, lambda: tr).reply |
1290 tr.close() | 1292 tr.close() |
1291 except Exception, exc: | 1293 except Exception, exc: |
1292 exc.duringunbundle2 = True | 1294 exc.duringunbundle2 = True |
1293 raise | 1295 raise |
1294 else: | 1296 else: |
1297 lock = repo.lock() | |
1295 r = changegroup.addchangegroup(repo, cg, source, url) | 1298 r = changegroup.addchangegroup(repo, cg, source, url) |
1296 finally: | 1299 finally: |
1297 if tr is not None: | 1300 lockmod.release(tr, lock, wlock) |
1298 tr.release() | |
1299 lock.release() | |
1300 return r | 1301 return r |