1 # -*- coding: iso-8859-1 -*-
2 # vim: set expandtab tabstop=4 shiftwidth=4 :
4 from threading import Lock
6 _gettersetter_code = """
8 lock = getattr(self, '__%(attr)sLock')
10 val = getattr(self, '__%(attr)s')
14 if not hasattr(self, '__%(attr)sLock'):
15 setattr(self, '__%(attr)sLock', Lock())
16 lock = getattr(self, '__%(attr)sLock')
18 setattr(self, '__%(attr)s', val)
22 __all__ = ('SyncProp', 'Synchronizable', 'synchronized')
25 """Synchronized property.
26 When using a class attribute as an SyncProp object it protects the property
27 access and modification using a lock (mutex). You should allways inherit
28 from Synchronizable if you are using SyncProp's.
29 Note that SyncProp only works with non-mutable objects, because it will not
30 protect from method calls.
33 class MyClass(Synchronizable):
34 prop = SyncProp("My property.")
38 # c.__propLock.acquire()
40 # c.__propLock.release()
41 print c.prop # is like:
42 # c.__propLock.acquire()
44 # c.__propLock.release()
48 def __init__(self, docstring=''):
52 class SynchronizableMeta(type):
53 """Synchronizable meta class.
54 This is the class that makes all the magic. It translate SyncProp attributes
55 to the synchronized properties.
57 def __new__(cls, clsname, bases, attrs):
58 "Translates SyncProp attributes to the synchronized properties."
59 cls = type.__new__(cls, clsname, bases, attrs)
60 for (attr, obj) in attrs.iteritems():
61 if isinstance(obj, SyncProp):
62 exec _gettersetter_code % {'attr': attr}
63 setattr(cls, attr, property(get, set, None, obj.doc))
66 class Synchronizable(object):
67 """Synchronizable classes base.
68 All the classes winth SyncProp attributes should inherit from this class to
69 wrap the SyncProp attributes between locks (mutexes).
72 class MyClass(Synchronizable):
73 prop = SyncProp("My property.")
77 # c.__propLock.acquire()
79 # c.__propLock.release()
80 print c.prop # is like:
81 # c.__propLock.acquire()
83 # c.__propLock.release()
88 __metaclass__ = SynchronizableMeta
90 def synchronized(lockattrname=None):
91 """Synchronized method decorator.
92 This decorator make a method call synchronized. It's not required to
93 inherit classes with synchronized methods from Synchrnonizable. You
94 can optionally pass to the decorator the name of the lock (mutex)
100 def syncMethod(self, msg):
101 print self.__name__, msg
104 c.syncMethod("hi!") # is like:
105 # c.__syncMethodLock.acquire()
106 # c.synchMethod("hi!")
107 # c.__syncMethodLock.release()
111 def syncMethod(self, *args, **kargs):
115 name = '__' + method.__name__ + 'Lock'
116 if not hasattr(self, name):
117 setattr(self, name, Lock())
118 lock = getattr(self, name)
120 ret = method(self, *args, **kargs)
127 if __name__ == '__main__':
130 from threading import Thread, enumerate, currentThread, Lock
135 class SyncObj(Synchronizable):
137 value = SyncProp("Dummy value")
140 name = currentThread().getName()
141 print name, 'durmiendo'
142 time.sleep(float('0.'+name))
143 sleep = synchronized(sleep)
146 for i in xrange(100):
148 obj.value = 0xf0f0f0f0f0f0f0+(i<<20)+(i<<14)+(i<<6)
150 #time.sleep(0.0000014)
156 obj.value = 100000000000000000000000000000
157 for i in xrange(200):
158 Thread(target=incObj, name=str(i+1)).start()
159 for t in enumerate():
160 if t is not currentThread():