Skip to content

Commit 3e99cc5

Browse files
committed
Port FileLock to Windows
Signed-off-by: Sebastian Ramacher <sebastian+dev@ramacher.at>
1 parent a6fef36 commit 3e99cc5

File tree

1 file changed

+71
-18
lines changed

1 file changed

+71
-18
lines changed

bpython/filelock.py

Lines changed: 71 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
# The MIT License
44
#
5-
# Copyright (c) 2015 Sebastian Ramacher
5+
# Copyright (c) 2015-2016 Sebastian Ramacher
66
#
77
# Permission is hereby granted, free of charge, to any person obtaining a copy
88
# of this software and associated documentation files (the "Software"), to deal
@@ -30,33 +30,86 @@
3030
except ImportError:
3131
has_fcntl = False
3232

33+
try:
34+
import msvcrt
35+
has_msvcrt = True
36+
except ImportError:
37+
has_msvcrt = False
38+
39+
40+
class BaseLock(object):
41+
"""Base class for file locking
42+
"""
43+
44+
def __init__(self, fd):
45+
self.fd = fd
46+
self.locked = False
3347

34-
class FileLock(object):
35-
"""Simple file locking
48+
def acquire(self):
49+
pass
3650

37-
On platforms without fcntl, all operations in this class are no-ops.
51+
def release(self):
52+
pass
53+
54+
def __enter__(self):
55+
self.acquire()
56+
57+
def __exit__(self, *args):
58+
if self.locked:
59+
self.release()
60+
61+
def __del__(self):
62+
if self.locked:
63+
self.release()
64+
65+
66+
class UnixFileLock(BaseLock):
67+
"""Simple file locking for Unix using fcntl
3868
"""
3969

4070
def __init__(self, fd, mode=None):
41-
if has_fcntl and mode is None:
42-
mode = fcntl.LOCK_EX
71+
super(UnixFileLock, self).__init__(fd)
4372

44-
self.fd = fd
73+
if mode is None:
74+
mode = fcntl.LOCK_EX
4575
self.mode = mode
76+
77+
def acquire(self):
78+
try:
79+
fcntl.flock(self.fd, self.mode)
80+
self.locked = True
81+
except IOError as e:
82+
if e.errno != errno.ENOLCK:
83+
raise e
84+
return self
85+
86+
def release(self):
87+
fcntl.flock(self.fd, fcntl.LOCK_UN)
4688
self.locked = False
4789

48-
def __enter__(self):
49-
if has_fcntl:
50-
try:
51-
fcntl.flock(self.fd, self.mode)
52-
self.locked = True
53-
except IOError as e:
54-
if e.errno != errno.ENOLCK:
55-
raise e
90+
91+
class WindowsFileLock(BaseLock):
92+
"""Simple file locking for Windows using msvcrt
93+
"""
94+
95+
def __init__(self, fd, mode=None):
96+
super(WindowsFileLock, self).__init__(fd)
97+
98+
def acquire(self):
99+
msvcrt.locking(self.fd, msvcrt.LK_NBLCK, 1)
100+
self.locked = True
56101
return self
57102

58-
def __exit__(self, *args):
59-
if has_fcntl and self.locked:
60-
fcntl.flock(self.fd, fcntl.LOCK_UN)
103+
def release(self):
104+
msvcrt.locking(self.fd, msvcrt.LK_UNLCK, 1)
105+
self.locked = False
106+
107+
108+
if has_fcntl:
109+
FileLock = UnixFileLock
110+
elif has_msvcrt:
111+
FileLock = WindowsFileLock
112+
else:
113+
FileLock = BaseLock
61114

62115
# vim: sw=4 ts=4 sts=4 ai et

0 commit comments

Comments
 (0)