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