author | Alberto Bertogli
<albertogli@telpin.com.ar> 2006-06-18 18:28:07 UTC |
committer | Alberto Bertogli
<albertogli@telpin.com.ar> 2006-06-18 18:28:07 UTC |
parent | 23eb152a88bf7cfdc31c7a5ce2adeb03c6b1257c |
dataflow.py | +59 | -0 |
samples/dataflow/sample2.py | +21 | -0 |
diff --git a/dataflow.py b/dataflow.py index 6ab8f80..fe2c553 100644 --- a/dataflow.py +++ b/dataflow.py @@ -4,6 +4,7 @@ dataflow - Objects with dataflow semantics Alberto Bertogli (albertogli@telpin.com.ar) """ +import thread import threading class DFObject(object): @@ -36,3 +37,61 @@ class DFObject(object): self.__lock.release() +class _DFWrapper: + """Dataflow wrapper class for the decorator defined below. + It's closely related so don't use it. + + We don't use a new-style class, otherwise we would have to implement + stub methods for __getattribute__, __hash__ and lots of others that + are inherited from object by default. This works too and is simple. + I'll deal with them when they become mandatory. + """ + def __init__(self): + self._override = True + self._isset = False + self._value = None + self._lock = threading.Condition() + self._override = False + + def _wait(self): + self._lock.acquire() + while not self._isset: + self._lock.wait() + self._lock.release() + + def __getattr__(self, name): + if self.__dict__['_override']: + return self.__dict__[name] + self._wait() + return getattr(self._value, name) + + def __setattr__(self, name, val): + if name == '_override' or self._override: + self.__dict__[name] = val + return + self._wait() + setattr(self._value, name, val) + return + +def dataflow(f): + "Dataflow decorator" + obj = _DFWrapper() + def threadedf(*args, **kwargs): + v = f(*args, **kwargs) + obj._override = True + olock = obj._lock + olock.acquire() + obj._value = v + obj._isset = True + obj._wait = lambda: True + obj._override = False + olock.notifyAll() + olock.release() + + def newf(*args, **kwargs): + thread.start_new_thread(threadedf, args, kwargs) + return obj + + return newf + + diff --git a/samples/dataflow/sample2.py b/samples/dataflow/sample2.py new file mode 100644 index 0000000..7d95171 --- /dev/null +++ b/samples/dataflow/sample2.py @@ -0,0 +1,21 @@ + +import dataflow +import time + + +def show(v): + print 'show() init + print' + print 'show() v: ' + str(v) + print 'show() done' + +@dataflow.dataflow +def set(): + print 'set() init + sleep' + time.sleep(1) + print 'set() returns 3' + return 3 + +v = set() +show(v) +show(v) +