22
22
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
23
# DEALINGS IN THE SOFTWARE.
24
24
import sys
25
+ import _thread
25
26
26
27
27
28
BLOCKLEN = 62
@@ -75,6 +76,7 @@ def __init__(self, iterable=None, maxlen=None):
75
76
else :
76
77
raise ValueError ("maxlen must be non-negative" )
77
78
79
+ self ._mutex = _thread .RLock ()
78
80
self ._maxlen = sys .maxsize if maxlen is None else maxlen
79
81
self .leftblock = Block (None , None )
80
82
self .rightblock = self .leftblock
@@ -87,6 +89,14 @@ def __init__(self, iterable=None, maxlen=None):
87
89
if iterable is not None :
88
90
self .extend (iterable )
89
91
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
90
100
def pop (self ):
91
101
"""Remove and return the rightmost element."""
92
102
if self .len == 0 :
@@ -123,16 +133,19 @@ def _checklock(self, lock):
123
133
if lock is not self ._lock :
124
134
raise RuntimeError ("deque mutated during iteration" )
125
135
136
+ @synchronized
126
137
def _trimleft (self ):
127
138
if self .len > self ._maxlen :
128
139
self .popleft ()
129
140
assert self .len == self ._maxlen
130
141
142
+ @synchronized
131
143
def _trimright (self ):
132
144
if self .len > self ._maxlen :
133
145
self .pop ()
134
146
assert self .len == self ._maxlen
135
147
148
+ @synchronized
136
149
def append (self , x ):
137
150
"""Add an element to the right side of the deque."""
138
151
ri = self .rightindex + 1
@@ -147,6 +160,7 @@ def append(self, x):
147
160
self ._trimleft ()
148
161
self ._modified ()
149
162
163
+ @synchronized
150
164
def appendleft (self , x ):
151
165
"""Add an element to the left side of the deque."""
152
166
li = self .leftindex - 1
@@ -161,6 +175,7 @@ def appendleft(self, x):
161
175
self ._trimright ()
162
176
self ._modified ()
163
177
178
+ @synchronized
164
179
def clear (self ):
165
180
"""Remove all elements from the deque."""
166
181
self .leftblock = Block (None , None )
@@ -170,6 +185,7 @@ def clear(self):
170
185
self .len = 0
171
186
self ._modified ()
172
187
188
+ @synchronized
173
189
def count (self , v ):
174
190
"""Return number of occurrences of value."""
175
191
b = self .leftblock
@@ -194,6 +210,7 @@ def count(self, v):
194
210
195
211
return count
196
212
213
+ @synchronized
197
214
def extend (self , iterable ):
198
215
"""Extend the right side of the deque with elements from the iterable"""
199
216
# Handle case where id(deque) == id(iterable)
@@ -228,6 +245,7 @@ def __rmul__(self, times):
228
245
def __hash__ (self ):
229
246
raise TypeError ("unhashable type: '%s'" % self .__name__ )
230
247
248
+ @synchronized
231
249
def extendleft (self , iterable ):
232
250
"""Extend the left side of the deque with elements from the iterable"""
233
251
# Handle case where id(deque) == id(iterable)
@@ -242,6 +260,7 @@ def extendleft(self, iterable):
242
260
break
243
261
self .appendleft (obj )
244
262
263
+ @synchronized
245
264
def popleft (self ):
246
265
"""Remove and return the leftmost element."""
247
266
if self .len == 0 :
@@ -266,6 +285,7 @@ def popleft(self):
266
285
self ._modified ()
267
286
return obj
268
287
288
+ @synchronized
269
289
def remove (self , x ):
270
290
"""Remove first occurrence of value."""
271
291
block = self .leftblock
@@ -286,6 +306,7 @@ def remove(self, x):
286
306
index = 0
287
307
raise ValueError ("deque.remove(x): x not in deque" )
288
308
309
+ @synchronized
289
310
def reverse (self ):
290
311
"""Reverse *IN PLACE*."""
291
312
li = self .leftindex
@@ -303,6 +324,7 @@ def reverse(self):
303
324
rb = rb .leftlink
304
325
ri = BLOCKLEN - 1
305
326
327
+ @synchronized
306
328
def rotate (self , n = 1 ):
307
329
"""Rotate the deque n steps to the right (default n=1). If n is negative, rotates left."""
308
330
len = self .len
@@ -343,6 +365,7 @@ def __repr__(self):
343
365
maxlen_repr = ', maxlen=%d' % (self .maxlen ,)
344
366
return '%s(%s%s)' % (type (self ).__name__ , list_repr , maxlen_repr )
345
367
368
+ @synchronized
346
369
def __compare__ (self , other , op ):
347
370
if not isinstance (other , deque ):
348
371
return NotImplemented
@@ -415,6 +438,7 @@ def _check_index(self, idx):
415
438
if idx < 0 or idx >= self .len :
416
439
raise IndexError ("deque index out of range" )
417
440
441
+ @synchronized
418
442
def index (self , v , start = 0 , stop = None ):
419
443
if stop is None :
420
444
stop = self .len
@@ -517,6 +541,7 @@ def __delitem__(self, idx):
517
541
self ._check_index (idx )
518
542
self .delitem (idx )
519
543
544
+ @synchronized
520
545
def copy (self ):
521
546
"""Return a shallow copy of a deque."""
522
547
if self ._maxlen == sys .maxsize :
@@ -552,6 +577,8 @@ def maxlen(self):
552
577
else :
553
578
return self ._maxlen
554
579
580
+ del synchronized
581
+
555
582
556
583
class _DequeIter (object ):
557
584
def __init__ (self , dq ):
0 commit comments