Author: dmeyer
Date: Sat Mar 1 11:05:01 2008
New Revision: 3144
Log:
Improve kaa.synchronized. It can be used as decorator and with
with statements and supports any object as lock. This is similar
to synchronized in Java.
Added:
trunk/base/test/synchronized.py
Modified:
trunk/base/src/notifier/thread.py
Modified: trunk/base/src/notifier/thread.py
==============================================================================
--- trunk/base/src/notifier/thread.py (original)
+++ trunk/base/src/notifier/thread.py Sat Mar 1 11:05:01 2008
@@ -58,7 +58,6 @@
import fcntl
import socket
import errno
-import thread
import types
# notifier imports
@@ -129,20 +128,74 @@
return decorator
-def synchronized(lock=threading.Lock()):
+class synchronized(object):
"""
- Synchronization decorator. This decorator does not work
- together with coroutines (yet).
- """
- def decorator(f):
- def newFunction(*args, **kw):
+ synchronized decorator and with statement similar to synchronized
+ in Java. When decorating a non-member function, a lock or any class
+ inheriting from object must be provided.
+ """
+ def __init__(self, obj=None):
+ if obj is None:
+ # decorator in classes
+ self._lock = None
+ return
+ if isinstance(obj, threading._RLock):
+ # decorator from functions
+ self._lock = obj
+ return
+ # with statement or function decorator with object
+ if not hasattr(obj, '_kaa_synchronized_lock'):
+ obj._kaa_synchronized_lock = threading.RLock()
+ self._lock = obj._kaa_synchronized_lock
+
+ def __enter__(self):
+ """
+ with statement enter
+ """
+ if self._lock is None:
+ raise RuntimeError('synchronized in with needs a parameter')
+ self._lock.acquire()
+ return self._lock
+
+ def __exit__(self, type, value, traceback):
+ """
+ with statement exit
+ """
+ self._lock.release()
+ return False
+
+ def __call__(self, func):
+ """
+ decorator init
+ """
+ def call(*args, **kwargs):
+ """
+ decorator call
+ """
+ lock = self._lock
+ if lock is None:
+ # Try to find out if the function is actually an instance
method.
+ # The decorator only sees a function object, even for methods,
so
+ # this kludge compares the code object of call (this wrapper)
+ # with the code object of the first argument's attribute of the
+ # function's name. If they're the same, then we must be
decorating
+ # a method, and we can attach the timer object to the instance
+ # instead of the function.
+ if args and call.func_code == \
+ getattr(getattr(args[0], func.func_name, None),
'func_code', None):
+ # first parameter is self, link lock to self
+ obj = args[0]
+ else:
+ obj = func
+ if not hasattr(obj, '_kaa_synchronized_lock'):
+ obj._kaa_synchronized_lock = threading.RLock()
+ lock = obj._kaa_synchronized_lock
lock.acquire()
try:
- return f(*args, **kw)
+ return func(*args, **kwargs)
finally:
lock.release()
- return newFunction
- return decorator
+ return call
def is_mainthread():
@@ -371,7 +424,7 @@
def _create_job(self, *args, **kwargs):
cb = Callback._get_callback(self)
- job = thread.ThreadInProgress(cb, *args, **kwargs)
+ job = ThreadInProgress(cb, *args, **kwargs)
job.priority = self.priority
if not _threads.has_key(self._thread):
_threads[self._thread] = _JobServer(self._thread)
Added: trunk/base/test/synchronized.py
==============================================================================
--- (empty file)
+++ trunk/base/test/synchronized.py Sat Mar 1 11:05:01 2008
@@ -0,0 +1,45 @@
+from __future__ import with_statement
+import threading
+import kaa
+
+class Test(object):
+
+ def foo(self):
+ with kaa.synchronized(self):
+ print 5
+
+ @kaa.synchronized()
+ def bar(self, x, y):
+ print 1, x, y
+
+
+# threading.Lock does NOT work
+lock = threading.RLock()
[EMAIL PROTECTED](lock)
+def foo():
+ print 6
+
+t = Test()
+
[EMAIL PROTECTED](t)
+def bar(x):
+ print 7, x
+
[EMAIL PROTECTED]()
+def zap(x):
+ print 9, x
+
[EMAIL PROTECTED]()
+def baz():
+ print 10
+
+t.bar(5, 9)
+t.foo()
+
+t2 = Test()
+t2.foo()
+
+foo()
+bar(8)
+zap(8)
+baz()
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Freevo-cvslog mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/freevo-cvslog