""" Implements a locked shelf using fcntl.lockf and shelve.Shelf.
"""
__author__ = "Piers Lauder, February 2003"
__licence__ = "GPL"
import anydbm, fcntl, os, shelve, time
class DbfilenameShelf(shelve.Shelf):
def __init__(self, filename, flag='c', protocol=None, writeback=False, binary=None):
self._lock_fd = -1
for retry in (2, 1, 0):
try:
db = anydbm.open(filename, flag)
break
except anydbm.error, val:
raise ValueError(val)
except:
if not retry:
raise
time.sleep(2.0 - (0.9*retry))
shelve.Shelf.__init__(self, db)
if flag != 'r':
mode, lock = os.O_RDWR, fcntl.LOCK_EX
else:
mode, lock = os.O_RDONLY, fcntl.LOCK_SH
for retry in (1, 0):
try:
self._lock_fd = os.open(filename, mode)
break
except OSError, val:
if not retry or os.path.exists(filename):
raise
open(filename, 'w').close()
fcntl.lockf(self._lock_fd, lock)
def close(self):
if self._lock_fd == -1:
return
shelve.Shelf.close(self)
fcntl.lockf(self._lock_fd, fcntl.LOCK_UN)
os.close(self._lock_fd)
self._lock_fd = -1
def open(filename, flag='c', protocol=None, writeback=False, binary=None):
"""Open a persistent dictionary for reading and writing.
The filename parameter is the base filename for the underlying
database. As a side-effect, an extension may be added to the
filename and more than one file may be created. The optional flag
parameter has the same interpretation as the flag parameter of
anydbm.open(). The optional protocol parameter specifies the
version of the pickle protocol (0, 1, or 2).
The optional binary parameter is deprecated and may be set to True
to force the use of binary pickles for serializing data values.
The database is locked for exclusive access until close.
"""
return DbfilenameShelf(filename, flag, protocol, writeback, binary)
# code highlighted using py2html.py version 0.8