Package glue :: Module pidfile
[hide private]
[frames] | no frames]

Source Code for Module glue.pidfile

 1  """ 
 2  A simple module for acquiring pidfile locks (e.g., for use by daemons). 
 3   
 4  Copyright (C) 2010 by Peter F. Couvares, Syracuse University 
 5  mailto: pfcouvar@syr.edu 
 6  """ 
 7   
 8  from __future__ import print_function 
 9  import os 
10  import sys 
11  import errno 
12  import fcntl 
13  import time 
14   
15  import glue.utils 
16   
17   
18  # from glue import git_version 
19   
20  # __author__ = 'Peter Couvares <pfcouvar@syr.edu>' 
21  # __version__ = "git id %s" % git_version.id 
22  #__date__ = git_version.date 
23   
24   
25 -def get_lock(lockfile):
26 """ 27 Tries to write a lockfile containing the current pid. Excepts if 28 the lockfile already contains the pid of a running process. 29 30 Although this should prevent a lock from being granted twice, it 31 can theoretically deny a lock unjustly in the unlikely event that 32 the original process is gone but another unrelated process has 33 been assigned the same pid by the OS. 34 """ 35 36 pidfile = open(lockfile, "a+") 37 38 # here we do some meta-locking by getting an exclusive lock on the 39 # pidfile before reading it, to prevent two daemons from seeing a 40 # stale lock at the same time, and both trying to run 41 try: 42 fcntl.flock(pidfile.fileno(), fcntl.LOCK_EX|fcntl.LOCK_NB) 43 except IOError as e: 44 raise RuntimeError("failed to lock %s: %s" % (lockfile, e)) 45 46 # we got the file lock, so check for a pid therein 47 pidfile.seek(0) 48 pidfile_pid = pidfile.readline().strip() 49 50 if pidfile_pid.isdigit(): 51 if glue.utils.pid_exists(int(pidfile_pid)): 52 raise RuntimeError("pidfile %s contains pid (%s) of a running " 53 "process" % (lockfile, pidfile_pid)) 54 else: 55 print ("pidfile %s contains stale pid %s; writing new lock" % 56 (lockfile, pidfile_pid)) 57 58 # the pidfile didn't exist or was stale, so grab a new lock 59 pidfile.truncate(0) 60 pidfile.write("%d\n" % os.getpid()) 61 pidfile.close() 62 63 # should be entirely unecessary, but paranoia always served me well 64 confirm_lock(lockfile) 65 return True
66 67
68 -def confirm_lock(lockfile):
69 """ 70 Confirm that the given lockfile contains our pid. 71 Should be entirely unecessary, but paranoia always served me well. 72 """ 73 pidfile = open(lockfile, "r") 74 pidfile_pid = pidfile.readline().strip() 75 pidfile.close() 76 if int(pidfile_pid) != os.getpid(): 77 raise RuntimeError("pidfile %s contains pid %s; expected pid %s!" % 78 (lockfile, os.getpid(), pidfile_pid)) 79 return True
80