-
Notifications
You must be signed in to change notification settings - Fork 7
/
userlocks.py
74 lines (57 loc) · 2.09 KB
/
userlocks.py
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
import os
import platform
import ctypes
import time
import datetime
class BaseUserLock(object):
def __init__(self, filename):
self.filename = filename
self.locktime = None
def __enter__(self):
dirname = os.path.split(os.path.abspath(self.filename))[0]
if not os.path.exists(dirname):
os.makedirs(dirname)
while True:
if self.tryacquire(self.filename):
break
print("Lockfile " + self.filename + " not available.")
print("Wait 30s...")
time.sleep(30.0)
self.locktime = datetime.datetime.now()
print("Lock acquired at " + str(self.locktime))
def __exit__(self, etype, einstance, etraceback):
self.release()
unlocktime = datetime.datetime.now()
print("Lock released at " + str(unlocktime))
print("Lock was held for " + str(unlocktime - self.locktime))
class WindowsUserLock(BaseUserLock):
def __init__(self, name):
BaseUserLock.__init__(self, os.environ["APPDATA"] + "\\openhome-build\\" + name + ".lock")
def tryacquire(self, filename):
self.handle = ctypes.windll.kernel32.CreateFileA(filename, 7, 0, 0, 2, 0x04000100, 0)
return self.handle != -1
def release(self):
ctypes.windll.kernel32.CloseHandle(self.handle)
class PosixUserLock(BaseUserLock):
def __init__(self, name):
BaseUserLock.__init__(self, os.environ["HOME"] + "/.openhome-build/" + name + ".lock")
def tryacquire(self, filename):
import fcntl
self.f = open(filename, "w")
try:
fcntl.lockf(self.f, fcntl.LOCK_EX)
return True
except IOError:
self.f.close()
return False
def release(self):
self.f.close()
def userlock(name):
'''
Acquire a lock scoped to the local user. Only one build at a time can run
with the given name per user per machine. While waiting for the lock, prints
a notice to stdout every 30s.
'''
if platform.system() == 'Windows':
return WindowsUserLock(name)
return PosixUserLock(name)