A little bug fix
[jcd.git] / Syncronized.py
blobbc9b6bc1a33194972b873d753d370c9a784bad2f
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3 # vim: expandtab:shiftwidth=4:fileencoding=utf-8 :
5 # Copyright ® 2008 Fulvio Satta
7 # If you want contact me, send an email to Yota_VGA@users.sf.net
9 # This file is part of jcd
11 # jcd is free software; you can redistribute it and/or modify
12 # it under the terms of the GNU General Public License as published by
13 # the Free Software Foundation; either version 2 of the License, or
14 # (at your option) any later version.
16 # jcd is distributed in the hope that it will be useful,
17 # but WITHOUT ANY WARRANTY; without even the implied warranty of
18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 # GNU General Public License for more details.
21 # You should have received a copy of the GNU General Public License
22 # along with this program; if not, write to the Free Software
23 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 #TODO: Test, test, test
26 #TODO: Polishing
28 ##########################
29 ##### IMPORT SECTION #####
30 ##########################
32 from threading import RLock as _RLock
33 from threading import Condition as _Condition
34 from threading import currentThread as _CurrentThread
36 from inspect import isfunction as _isfunction
38 ################################
39 ##### BASE CLASSES SECTION #####
40 ################################
42 #Class usefull for sincronizzation purposes
43 class Syncronized:
44 def __init__(self):
45 self.__mutex = _RLock()
47 #Locking mutex
48 def lock(self, blocking = 1):
49 return self.__mutex.acquire(blocking)
51 #Unlocking mutex
52 def unlock(self):
53 return self.__mutex.release()
55 #Class usefull for sincronizzation purposes with rw locks
56 class RWSyncronized:
57 def __init__(self):
58 self.__status = _Condition()
59 self.__lock = _RLock()
60 self.__readers = 0
61 self.__writers = False
62 self.__usedThreads = {}
64 def __addToThread(self):
65 thread = _CurrentThread()
66 original = self.__usedThreads.get(thread, 0)
67 self.__usedThreads[thread] = original + 1
68 return original
70 #Locking for read
71 def readLock(self, wait = None):
72 self.__status.lock()
73 try:
74 if self.__addToThread():
75 return True
77 while True:
78 if self.__writers:
79 self.__status.wait(wait)
80 continue
82 r = True
83 if not self.__readers:
84 r = self.__lock.acquire()
86 self.__readers += 1
87 return r
88 finally:
89 self.__status.release()
91 #Locking for write
92 def writeLock(self, blocking = 1):
93 self.__status.acquire()
94 try:
95 self.__addToThread()
96 self.__writers = True
97 return self.__lock.acquire(blocking)
98 finally:
99 self.__status.release()
101 #Unlocking the rwlock
102 def rwunlock(self):
103 self.__status.acquire()
104 try:
105 thread = _CurrentThread()
106 self.__usedThreads[thread] -= 1
107 if self.__usedThreads[thread]:
108 del self.__usedThreads[thread]
110 if self.__readers:
111 self.__readers -= 1
112 if not self.__readers:
113 self.__lock.release()
114 finally:
115 self.__status.release()
117 ##############################
118 ##### DECORATORS SECTION #####
119 ##############################
121 #Decorator for function autolock in the classes inerithed from Syncronized
122 def AutoLock(param):
123 from types import FunctionType
125 def member(self, *args, **kwargs):
126 self.lock()
127 try:
128 return param(self, *args, **kwargs)
129 finally:
130 self.unlock()
132 def function(f):
133 def decorator(*args, **kwargs):
134 if hasattr(param, 'lock'):
135 param.lock()
136 else:
137 param.acquire()
138 try:
139 return f(*args, **kwargs)
140 finally:
141 if hasattr(param, 'unlock'):
142 param.unlock()
143 else:
144 param.release()
145 return decorator
147 if type(param) == FunctionType:
148 return member
149 return function
151 #Decorator for function autolock in the classes inerithed from RWSyncronized
152 def RWAutoLock(param, write = False):
153 from types import FunctionType
155 def member(self, *args, **kwargs):
156 if write:
157 self.writeLock()
158 else:
159 self.readLock()
160 try:
161 return param(self, *args, **kwargs)
162 finally:
163 self.rwunlock()
165 def function(f):
166 def decorator(*args, **kwargs):
167 if write:
168 param.writeLock()
169 else:
170 param.readLock()
171 try:
172 return f(*args, **kwargs)
173 finally:
174 param.rwunlock()
175 return decorator
177 if type(param) == FunctionType:
178 return member
179 return function
181 ########################
182 ##### TEST SECTION #####
183 ########################
185 if __name__ == '__main__':
186 class Try1(Syncronized):
187 pass
189 t1 = Try1()
190 t1.lock()
191 t1.lock()
192 t1.unlock()
193 t1.unlock()