2222# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2323# DEALINGS IN THE SOFTWARE.
2424import sys
25+ import _thread
2526
2627
2728BLOCKLEN = 62
@@ -75,6 +76,7 @@ def __init__(self, iterable=None, maxlen=None):
7576 else :
7677 raise ValueError ("maxlen must be non-negative" )
7778
79+ self ._mutex = _thread .RLock ()
7880 self ._maxlen = sys .maxsize if maxlen is None else maxlen
7981 self .leftblock = Block (None , None )
8082 self .rightblock = self .leftblock
@@ -87,6 +89,14 @@ def __init__(self, iterable=None, maxlen=None):
8789 if iterable is not None :
8890 self .extend (iterable )
8991
92+ def synchronized (fun ):
93+ def fun_synchronized (self , * args ):
94+ with self ._mutex :
95+ return fun (self , * args )
96+ return fun_synchronized
97+
98+
99+ @synchronized
90100 def pop (self ):
91101 """Remove and return the rightmost element."""
92102 if self .len == 0 :
@@ -123,16 +133,19 @@ def _checklock(self, lock):
123133 if lock is not self ._lock :
124134 raise RuntimeError ("deque mutated during iteration" )
125135
136+ @synchronized
126137 def _trimleft (self ):
127138 if self .len > self ._maxlen :
128139 self .popleft ()
129140 assert self .len == self ._maxlen
130141
142+ @synchronized
131143 def _trimright (self ):
132144 if self .len > self ._maxlen :
133145 self .pop ()
134146 assert self .len == self ._maxlen
135147
148+ @synchronized
136149 def append (self , x ):
137150 """Add an element to the right side of the deque."""
138151 ri = self .rightindex + 1
@@ -147,6 +160,7 @@ def append(self, x):
147160 self ._trimleft ()
148161 self ._modified ()
149162
163+ @synchronized
150164 def appendleft (self , x ):
151165 """Add an element to the left side of the deque."""
152166 li = self .leftindex - 1
@@ -161,6 +175,7 @@ def appendleft(self, x):
161175 self ._trimright ()
162176 self ._modified ()
163177
178+ @synchronized
164179 def clear (self ):
165180 """Remove all elements from the deque."""
166181 self .leftblock = Block (None , None )
@@ -170,6 +185,7 @@ def clear(self):
170185 self .len = 0
171186 self ._modified ()
172187
188+ @synchronized
173189 def count (self , v ):
174190 """Return number of occurrences of value."""
175191 b = self .leftblock
@@ -194,6 +210,7 @@ def count(self, v):
194210
195211 return count
196212
213+ @synchronized
197214 def extend (self , iterable ):
198215 """Extend the right side of the deque with elements from the iterable"""
199216 # Handle case where id(deque) == id(iterable)
@@ -228,6 +245,7 @@ def __rmul__(self, times):
228245 def __hash__ (self ):
229246 raise TypeError ("unhashable type: '%s'" % self .__name__ )
230247
248+ @synchronized
231249 def extendleft (self , iterable ):
232250 """Extend the left side of the deque with elements from the iterable"""
233251 # Handle case where id(deque) == id(iterable)
@@ -242,6 +260,7 @@ def extendleft(self, iterable):
242260 break
243261 self .appendleft (obj )
244262
263+ @synchronized
245264 def popleft (self ):
246265 """Remove and return the leftmost element."""
247266 if self .len == 0 :
@@ -266,6 +285,7 @@ def popleft(self):
266285 self ._modified ()
267286 return obj
268287
288+ @synchronized
269289 def remove (self , x ):
270290 """Remove first occurrence of value."""
271291 block = self .leftblock
@@ -286,6 +306,7 @@ def remove(self, x):
286306 index = 0
287307 raise ValueError ("deque.remove(x): x not in deque" )
288308
309+ @synchronized
289310 def reverse (self ):
290311 """Reverse *IN PLACE*."""
291312 li = self .leftindex
@@ -303,6 +324,7 @@ def reverse(self):
303324 rb = rb .leftlink
304325 ri = BLOCKLEN - 1
305326
327+ @synchronized
306328 def rotate (self , n = 1 ):
307329 """Rotate the deque n steps to the right (default n=1). If n is negative, rotates left."""
308330 len = self .len
@@ -343,6 +365,7 @@ def __repr__(self):
343365 maxlen_repr = ', maxlen=%d' % (self .maxlen ,)
344366 return '%s(%s%s)' % (type (self ).__name__ , list_repr , maxlen_repr )
345367
368+ @synchronized
346369 def __compare__ (self , other , op ):
347370 if not isinstance (other , deque ):
348371 return NotImplemented
@@ -415,6 +438,7 @@ def _check_index(self, idx):
415438 if idx < 0 or idx >= self .len :
416439 raise IndexError ("deque index out of range" )
417440
441+ @synchronized
418442 def index (self , v , start = 0 , stop = None ):
419443 if stop is None :
420444 stop = self .len
@@ -517,6 +541,7 @@ def __delitem__(self, idx):
517541 self ._check_index (idx )
518542 self .delitem (idx )
519543
544+ @synchronized
520545 def copy (self ):
521546 """Return a shallow copy of a deque."""
522547 if self ._maxlen == sys .maxsize :
@@ -552,6 +577,8 @@ def maxlen(self):
552577 else :
553578 return self ._maxlen
554579
580+ del synchronized
581+
555582
556583class _DequeIter (object ):
557584 def __init__ (self , dq ):
0 commit comments