Coverage for python/lsst/ctrl/orca/multithreading/SharedData.py : 15%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
# # LSST Data Management System # Copyright 2008, 2009, 2010 LSST Corporation. # # This product includes software developed by the # LSST Project (http://www.lsst.org/). # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the LSST License Statement and # the GNU General Public License along with this program. If not, # see <http://www.lsstcorp.org/LegalNotices/>. #
#
"""A lock-protected container for data that can be shared amongst threads.
Parameters ---------- needLockOnRead : `bool` If true (default), acquiring the lock will be needed when reading the data. This is recommended if the data items are anything but primitive types; otherwise, a compound data item (e.g. of type dict) could be updated without acquiring a lock. data : `dict` A dictionary of data to initialize the container with. This is done by calling initData(). Set this value to False when calling from a subclass constructor; this will allow any non-protected attributes to be set via the subclass's constructor. If None is given (default), it is assumed that all new attributes will be considered protected data. cond : `bool` Reuse this existing Condition instance to protect this container
Notes ----- This container holds data that is intended to be shared amongst multiple threads. In order to update or (optionally) examine the data, one must first aquire the lock associated with the container.
This container also behaves like a threading.Container, via its wait(), notify(), and notifyAll() functions. Also like Condition, acquire() is reentrant.
SharedData instances may be used with the with statement:
sd = SharedData() with sd: sd.blah = 1
The with statement will acquire the lock and ensure that it is released when its block is exited. """
self._d = {} if cond is None: cond = threading.Condition() self._cond = cond
# behave like a Condition
# acquire method self.acquire = cond.acquire
# release method self.release = cond.release
# notify method self.notify = cond.notify
# notifyall method self.notifyAll = cond.notifyAll
# wait method self.wait = cond.wait self._is_owned = cond._is_owned
self._lockOnRead = needLockOnRead
if isinstance(data, dict): self.initData(data) if data is None: self._d["__"] = True
# overrides __enter__ return self._cond.__enter__(*args, **kwds)
# overrides __exit__ return self._cond.__exit__(*args, **kwds)
# overrides __getattribute__ if name == "_d" or len(self._d) == 0 or name not in self._d: return object.__getattribute__(self, name)
if self._lockOnRead and not self._is_owned(): raise AttributeError("%s: lock required for read access" % name) return self._d[name]
# overrides __setattr__ if name == "_d" or len(self._d) == 0 or name in self.__dict__: object.__setattr__(self, name, value) return
if not self._is_owned(): raise AttributeError("%s: lock required for write access" % name)
self._d[name] = value
"""Initialize the container with the data from a dictionary.
Parameters ---------- data : `dict` A dictionary of data to initialize the container with. Attributes will be added to this container with names matching the given the dictionary's key names and initialized to their corresponding values. The keys cannot match an existing function (or internal attribute) name.
Raises ------ ValueError if the dictionary has a key that conflicts with an existing function or internal attribute name. """ with self._cond: bad = [] realattrs = self.__dict__ for key in data: if key in realattrs: bad.append(key) if len(bad) > 0: raise ValueError("Names cause conflicts with functions or " + "internal data: " + str(bad))
for key in data: self._d[key] = data[key]
if len(self._d) == 0: self._d["__"] = True
# overrides dir() method return [k for k in self._d if k != "__"] |