comparison mercurial/util.py @ 1877:d314a89fa4f1

change lock format to let us detect and break stale locks. old style: symlink to pid new style: symlink to hostname:pid if lock code finds new-style lock, it breaks lock if locking pid is on same machine and pid is not alive. otherwise, lock is left alone. this makes locking code safe with old-style locks and with locks on other machines. new code makes server part of mercurial more robust in case machine crashes, power fails, or crazy user does kill -9.
author Vadim Gelfer <vadim.gelfer@gmail.com>
date Fri, 10 Mar 2006 08:31:31 -0800
parents bdfb524d728a
children 05c7d75be925
comparison
equal deleted inserted replaced
1876:2e0fd78587bd 1877:d314a89fa4f1
497 if pf[0] == '`': 497 if pf[0] == '`':
498 pf = pf[1:-1] # Remove the quotes 498 pf = pf[1:-1] # Remove the quotes
499 return pf 499 return pf
500 500
501 try: # ActivePython can create hard links using win32file module 501 try: # ActivePython can create hard links using win32file module
502 import win32file 502 import win32api, win32con, win32file
503 503
504 def os_link(src, dst): # NB will only succeed on NTFS 504 def os_link(src, dst): # NB will only succeed on NTFS
505 win32file.CreateHardLink(dst, src) 505 win32file.CreateHardLink(dst, src)
506 506
507 def nlinks(pathname): 507 def nlinks(pathname):
514 fh.Close() 514 fh.Close()
515 return res[7] 515 return res[7]
516 except: 516 except:
517 return os.stat(pathname).st_nlink 517 return os.stat(pathname).st_nlink
518 518
519 def testpid(pid):
520 '''return False if pid is dead, True if running or not known'''
521 try:
522 win32api.OpenProcess(win32con.PROCESS_QUERY_INFORMATION,
523 False, pid)
524 except:
525 return True
526
519 except ImportError: 527 except ImportError:
520 pass 528 def testpid(pid):
529 '''return False if pid dead, True if running or not known'''
530 return True
521 531
522 def is_exec(f, last): 532 def is_exec(f, last):
523 return last 533 return last
524 534
525 def set_exec(f, mode): 535 def set_exec(f, mode):
611 except OSError, why: 621 except OSError, why:
612 if why.errno == errno.EINVAL: 622 if why.errno == errno.EINVAL:
613 return _readlock_file(pathname) 623 return _readlock_file(pathname)
614 else: 624 else:
615 raise 625 raise
626
627 def testpid(pid):
628 '''return False if pid dead, True if running or not sure'''
629 try:
630 os.kill(pid, 0)
631 return True
632 except OSError, inst:
633 return inst.errno != errno.ESRCH
616 634
617 def explain_exit(code): 635 def explain_exit(code):
618 """return a 2-tuple (desc, code) describing a process's status""" 636 """return a 2-tuple (desc, code) describing a process's status"""
619 if os.WIFEXITED(code): 637 if os.WIFEXITED(code):
620 val = os.WEXITSTATUS(code) 638 val = os.WEXITSTATUS(code)