summaryrefslogtreecommitdiff
path: root/taskflow/utils
diff options
context:
space:
mode:
authorJoshua Harlow <harlowja@gmail.com>2016-02-08 23:16:58 -0800
committerJoshua Harlow <harlowja@gmail.com>2016-02-08 23:16:58 -0800
commitb033fa672227720ae64bca25eafffc87d5fea42a (patch)
tree827ac619760ba6c55683ffcdebf79c94397ebfda /taskflow/utils
parent61efc31e965b8defac84aa494095fd3734f739eb (diff)
downloadtaskflow-b033fa672227720ae64bca25eafffc87d5fea42a.tar.gz
Allow cachedproperty to avoid locking
Under some cirumstances it is ok to recompute a value when raced to by multiple threads, for these cases allow the cachedproperty to avoid needing and using a lock. Change-Id: Icb71cb5ea280185cfb120671be900435dabcd50b
Diffstat (limited to 'taskflow/utils')
-rw-r--r--taskflow/utils/misc.py33
1 files changed, 21 insertions, 12 deletions
diff --git a/taskflow/utils/misc.py b/taskflow/utils/misc.py
index 5c2bf4f..3798a45 100644
--- a/taskflow/utils/misc.py
+++ b/taskflow/utils/misc.py
@@ -350,8 +350,11 @@ class cachedproperty(object):
cached property would be stored under '_get_thing' in the self object
after the first call to 'get_thing' occurs.
"""
- def __init__(self, fget):
- self._lock = threading.RLock()
+ def __init__(self, fget=None, require_lock=True):
+ if require_lock:
+ self._lock = threading.RLock()
+ else:
+ self._lock = None
# If a name is provided (as an argument) then this will be the string
# to place the cached attribute under if not then it will be the
# function itself to be wrapped into a property.
@@ -365,10 +368,12 @@ class cachedproperty(object):
self.__doc__ = None
def __call__(self, fget):
- # If __init__ received a string then this will be the function to be
- # wrapped as a property (if __init__ got a function then this will not
- # be called).
+ # If __init__ received a string or a lock boolean then this will be
+ # the function to be wrapped as a property (if __init__ got a
+ # function then this will not be called).
self._fget = fget
+ if not self._attr_name:
+ self._attr_name = "_%s" % (fget.__name__)
self.__doc__ = getattr(fget, '__doc__', None)
return self
@@ -387,13 +392,17 @@ class cachedproperty(object):
if hasattr(instance, self._attr_name):
return getattr(instance, self._attr_name)
else:
- with self._lock:
- try:
- return getattr(instance, self._attr_name)
- except AttributeError:
- value = self._fget(instance)
- setattr(instance, self._attr_name, value)
- return value
+ if self._lock is not None:
+ self._lock.acquire()
+ try:
+ return getattr(instance, self._attr_name)
+ except AttributeError:
+ value = self._fget(instance)
+ setattr(instance, self._attr_name, value)
+ return value
+ finally:
+ if self._lock is not None:
+ self._lock.release()
def millis_to_datetime(milliseconds):