-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpidFile.py
More file actions
executable file
·105 lines (89 loc) · 2.36 KB
/
pidFile.py
File metadata and controls
executable file
·105 lines (89 loc) · 2.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#!/usr/bin/env python
# A Utility script with functions to create locks in a safe way for running processes.
# Will ensure only the process that has
# obtained the lock with registerPid() is the only one that runs.
# registerPid(),unregisterPid() will be called from the parent process
import os, os.path
from fcntl import LOCK_UN, LOCK_EX,LOCK_NB, flock
#import struct
#MAXPIDBYTE=struct.calcsize("P")
MAXPIDBYTE=8
MAXPID=65536
def __lockFile(fd,nonBlock=True):
try:
if nonBlock:
flock(fd,LOCK_EX|LOCK_NB)
else:
flock(fd,LOCK_EX)
except Exception,e:
return False
return True
def __unLockFile(fd):
flock(fd, LOCK_UN)
def registerPid(pidFile, forceRun=False):
pid = os.getpid()
try:
fd=os.open(pidFile, os.O_CREAT|os.O_WRONLY|os.O_EXCL)
if __lockFile(fd):
os.write(fd, str(pid))
__unLockFile(fd)
os.close(fd)
return True
except OSError, e:
if e.errno == os.errno.EEXIST:
#read pid from existing file
try:
fd=os.open(pidFile, os.O_RDWR|os.O_EXCL|os.O_NONBLOCK)
if __lockFile(fd):
os.lseek(fd,0,0)
opid=os.read(fd,MAXPIDBYTE)
#Check if opid is currently running process
#otherwise no other instance is running, write current pid
#to the file and return True
try:
if opid.strip() == "":
opid = MAXPID + 1
else:
opid = int(opid)
os.kill( opid,0)
except OSError, e:
if e.errno == os.errno.ESRCH:
os.ftruncate(fd,0)
os.lseek(fd,0,0)
spid=str(pid)
os.write(fd, spid)
__unLockFile(fd)
os.close(fd)
return True
else:
raise OSError(e)
#Else another process is running or has locked pidFile
except OSError,e:
#file has been opened by another process
if e.errno == os.errno.EBUSY:
return forceRun
else:
raise OSError(e)
finally:
try:
os.close(fd)
except:
pass
return forceRun
def unregisterPid(pidFile):
pid=os.getpid()
try:
#Open file, obtain lock and remove if this test process owns it
#This will block. Not sure O_EXCL is not ignored
fd= os.open(pidFile, os.O_RDONLY|os.O_EXCL)
if __lockFile(fd, False):
apid = os.read(fd,MAXPIDBYTE)
if str(pid) == apid.strip():
__unLockFile(fd)
os.close(fd)
os.remove(pidFile)
else:
__unLockFile(fd)
os.close(fd)
except Exception, e:
pass