[h5py] 340/455: Change per-file locking system, and allow manual binding of File objects
Ghislain Vaillant
ghisvail-guest at moszumanska.debian.org
Thu Jul 2 18:19:48 UTC 2015
This is an automated email from the git hooks/post-receive script.
ghisvail-guest pushed a commit to annotated tag 1.3.0
in repository h5py.
commit dbd335d476f33ddb016ed6fad49a29d4435d446d
Author: andrewcollette <andrew.collette at gmail.com>
Date: Tue Jan 5 01:04:32 2010 +0000
Change per-file locking system, and allow manual binding of File objects
---
h5py/highlevel.py | 120 +++++++++++++++++++++++++++++++++---------------------
1 file changed, 73 insertions(+), 47 deletions(-)
diff --git a/h5py/highlevel.py b/h5py/highlevel.py
index e6ce09b..4506aee 100644
--- a/h5py/highlevel.py
+++ b/h5py/highlevel.py
@@ -34,6 +34,7 @@ import math
import os.path as op
import posixpath as pp
+import weakref
from h5py import h5, h5f, h5g, h5s, h5t, h5d, h5a, \
h5p, h5r, h5z, h5i, h5fd, h5o, h5l, \
@@ -92,7 +93,7 @@ class HLObject(object):
"""Name of this object in the HDF5 file. Not necessarily unique."""
name = h5i.get_name(self.id)
if name is None and config.API_18:
- name = h5py.h5r.get_name(self.ref)
+ name = h5r.get_name(self.ref)
return name
@property
@@ -102,10 +103,13 @@ class HLObject(object):
@property
def file(self):
- """Return the File instance associated with this object"""
- if hasattr(self, '_file'):
- return self._file
- return self
+ """Return a File instance associated with this object"""
+ if isinstance(self, File):
+ return self
+ if not hasattr(self, '_file'):
+ fid = h5i.get_file_id(self.id)
+ self._file = File(None, bind=fid)
+ return self._file
@property
def parent(self):
@@ -124,11 +128,7 @@ class HLObject(object):
@property
def _lock(self):
- return self.file._fidlock
-
- def __init__(self, parent):
- if parent is not self:
- self._file = parent.file
+ return self.file._lock
def __nonzero__(self):
return self.id.__nonzero__()
@@ -234,7 +234,6 @@ class Group(HLObject, _DictCompat):
calling the constructor directly.
"""
with parent_object._lock:
- HLObject.__init__(self, parent_object)
if _rawid is not None:
self.id = _rawid
elif create:
@@ -635,6 +634,21 @@ class File(Group):
memb_size: Maximum file size (default is 2**31-1).
"""
+ # We store locks by file hash, rather than manually associating them
+ # with particular File instances.
+ _locks = weakref.WeakKeyDictionary()
+
+ @property
+ def _lock(self):
+ """ Get an RLock for this file, creating it if necessary. Locks are
+ linked to the "real" underlying HDF5 file, regardless of the number
+ of File instances.
+ """
+ lock = self._locks.get(self)
+ if lock is None:
+ return self._locks.setdefault(self, threading.RLock())
+ return lock
+
@property
def filename(self):
"""File name on disk"""
@@ -665,7 +679,7 @@ class File(Group):
# --- Public interface (File) ---------------------------------------------
- def __init__(self, name, mode=None, driver=None, **driver_kwds):
+ def __init__(self, name, mode=None, driver=None, **kwds):
""" Create a new file object.
Valid modes (like Python's file() modes) are:
@@ -682,51 +696,65 @@ class File(Group):
- 'core' mmap driver
- 'family' Multi-part file driver
"""
+ if "bind" in kwds:
+ self.fid = kwds["bind"]
+ else:
+ if driver == 'core' and mode=='w-' and version.hdf5_version_tuple[0:2] == (1,6):
+ raise NotImplementedError("w- flag does not work on 1.6 for CORE driver")
+ try:
+ # If the byte string doesn't match the default encoding, just
+ # pass it on as-is. Note Unicode objects can always be encoded.
+ name = name.encode(sys.getfilesystemencoding())
+ except (UnicodeError, LookupError):
+ pass
+
+ plist = self._get_access_plist(driver, **kwds)
+ self.fid = self._get_fid(name, mode, plist)
+ self._mode = mode
+
+ self.id = self.fid # So the Group constructor can find it.
+ Group.__init__(self, self, '/')
+
+ def _get_access_plist(self, driver, **kwds):
+ """ Set up file access property list """
plist = h5p.create(h5p.FILE_ACCESS)
plist.set_fclose_degree(h5f.CLOSE_STRONG)
- if driver is not None and not (driver=='windows' and sys.platform=='win32'):
- if(driver=='sec2'):
- plist.set_fapl_sec2(**driver_kwds)
- elif(driver=='stdio'):
- plist.set_fapl_stdio(**driver_kwds)
- elif(driver=='core'):
- plist.set_fapl_core(**driver_kwds)
- elif(driver=='family'):
- plist.set_fapl_family(memb_fapl=plist.copy(), **driver_kwds)
- else:
- raise ValueError('Unknown driver type "%s"' % driver)
- try:
- # If the byte string doesn't match the default encoding, just
- # pass it on as-is. Note Unicode objects can always be encoded.
- name = name.encode(sys.getfilesystemencoding())
- except (UnicodeError, LookupError):
- pass
+ if driver is None or (driver=='windows' and sys.platform=='win32'):
+ return plist
+
+ if(driver=='sec2'):
+ plist.set_fapl_sec2(**kwds)
+ elif(driver=='stdio'):
+ plist.set_fapl_stdio(**kwds)
+ elif(driver=='core'):
+ plist.set_fapl_core(**kwds)
+ elif(driver=='family'):
+ plist.set_fapl_family(memb_fapl=plist.copy(), **kwds)
+ else:
+ raise ValueError('Unknown driver type "%s"' % driver)
+ return plist
+
+ def _get_fid(self, name, mode, plist):
+ """ Get a new FileID by opening or creating a file.
+ Also validates mode argument."""
if mode == 'r':
- self.fid = h5f.open(name, h5f.ACC_RDONLY, fapl=plist)
+ fid = h5f.open(name, h5f.ACC_RDONLY, fapl=plist)
elif mode == 'r+':
- self.fid = h5f.open(name, h5f.ACC_RDWR, fapl=plist)
+ fid = h5f.open(name, h5f.ACC_RDWR, fapl=plist)
elif mode == 'w-':
- if driver == 'core' and version.hdf5_version_tuple[0:2] == (1,6):
- raise NotImplementedError("w- flag does not work on 1.6 for CORE driver")
- self.fid = h5f.create(name, h5f.ACC_EXCL, fapl=plist)
+ fid = h5f.create(name, h5f.ACC_EXCL, fapl=plist)
elif mode == 'w':
- self.fid = h5f.create(name, h5f.ACC_TRUNC, fapl=plist)
+ fid = h5f.create(name, h5f.ACC_TRUNC, fapl=plist)
elif mode == 'a' or mode is None:
try:
- self.fid = h5f.open(name, h5f.ACC_RDWR, fapl=plist)
+ fid = h5f.open(name, h5f.ACC_RDWR, fapl=plist)
except IOError:
- self.fid = h5f.create(name, h5f.ACC_EXCL, fapl=plist)
-
+ fid = h5f.create(name, h5f.ACC_EXCL, fapl=plist)
else:
raise ValueError("Invalid mode; must be one of r, r+, w, w-, a")
-
- self._fidlock = threading.RLock()
- self.id = self.fid # So the Group constructor can find it.
- Group.__init__(self, self, '/')
-
- self._mode = mode
+ return fid
def close(self):
""" Close this HDF5 file. All open objects will be invalidated.
@@ -901,7 +929,6 @@ class Dataset(HLObject):
Please note none of these are allowed for scalar datasets.
"""
with group._lock:
- HLObject.__init__(self, group)
if _rawid is not None:
self.id = _rawid
elif data is None and shape is None:
@@ -1246,7 +1273,7 @@ class AttributeManager(_DictCompat):
@property
def _lock(self):
- return self._file._fidlock
+ return self._file._lock
def __getitem__(self, name):
""" Read the value of an attribute.
@@ -1388,7 +1415,6 @@ class Datatype(HLObject):
""" Private constructor.
"""
with grp._lock:
- HLObject.__init__(self, grp)
self.id = h5t.open(grp.id, name)
self._attrs = AttributeManager(self)
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/h5py.git
More information about the debian-science-commits
mailing list