@@ -143,36 +143,9 @@ def __init__(self, host, port=None, secure=None, window_manager=None,
143
143
144
144
# Concurrency
145
145
#
146
- # Use one lock (_lock) to synchronize any interaction with global
147
- # connection state, e.g. stream creation/deletion.
148
- #
149
- # It's ok to use the same in lock all these cases as they occur at
150
- # different/linked points in the connection's lifecycle.
151
- #
152
- # Use another 2 locks (_write_lock, _read_lock) to synchronize
153
- # - _send_cb
154
- # - _recv_cb
155
- # respectively.
156
- #
157
- # I.e, send/recieve on the connection and its streams are serialized
158
- # separately across the threads accessing the connection. This is a
159
- # simple way of providing thread-safety.
160
- #
161
- # _write_lock and _read_lock synchronize all interactions between
162
- # streams and the connnection. There is a third I/O callback,
163
- # _close_stream, passed to a stream's constructor. It does not need to
164
- # be synchronized, it uses _send_cb internally (which is serialized);
165
- # its other activity (safe deletion of the stream from self.streams)
166
- # does not require synchronization.
167
- #
168
- # _read_lock may be acquired when already holding the _write_lock,
169
- # when they both held it is always by acquiring _write_lock first.
170
- #
171
- # Either _read_lock or _write_lock may be acquired whilst holding _lock
172
- # which should always be acquired before either of the other two.
146
+ # Use one universal lock (_lock) to synchronize all interaction
147
+ # with global connection state, _send_cb and _recv_cb.
173
148
self ._lock = threading .RLock ()
174
- self ._write_lock = threading .RLock ()
175
- self ._read_lock = threading .RLock ()
176
149
177
150
# Create the mutable state.
178
151
self .__wm_class = window_manager or FlowControlManager
@@ -236,7 +209,7 @@ def ping(self, opaque_data):
236
209
:returns: Nothing
237
210
"""
238
211
self .connect ()
239
- with self ._write_lock :
212
+ with self ._lock :
240
213
with self ._conn as conn :
241
214
conn .ping (to_bytestring (opaque_data ))
242
215
self ._send_outstanding_data ()
@@ -275,7 +248,7 @@ def request(self, method, url, body=None, headers=None):
275
248
# If threads interleave these operations, it could result in messages
276
249
# being sent in the wrong order, which can lead to the out-of-order
277
250
# messages with lower stream IDs being closed prematurely.
278
- with self ._write_lock :
251
+ with self ._lock :
279
252
# Unlike HTTP/1.1, HTTP/2 (according to RFC 7540) doesn't require
280
253
# to use absolute URI when proxying.
281
254
@@ -483,10 +456,10 @@ def _send_outstanding_data(self, tolerate_peer_gone=False,
483
456
send_empty = True ):
484
457
# Concurrency
485
458
#
486
- # Hold _write_lock ; getting and writing data from _conn is synchronized
459
+ # Hold _lock ; getting and writing data from _conn is synchronized
487
460
#
488
461
# I/O occurs while the lock is held; waiting threads will see a delay.
489
- with self ._write_lock :
462
+ with self ._lock :
490
463
with self ._conn as conn :
491
464
data = conn .data_to_send ()
492
465
if data or send_empty :
@@ -576,9 +549,9 @@ def endheaders(self, message_body=None, final=False, stream_id=None):
576
549
577
550
# Concurrency:
578
551
#
579
- # Hold _write_lock : synchronize access to the connection's HPACK
552
+ # Hold _lock : synchronize access to the connection's HPACK
580
553
# encoder and decoder and the subsquent write to the connection
581
- with self ._write_lock :
554
+ with self ._lock :
582
555
stream .send_headers (headers_only )
583
556
584
557
# Send whatever data we have.
@@ -641,10 +614,10 @@ def _send_cb(self, data, tolerate_peer_gone=False):
641
614
"""
642
615
# Concurrency
643
616
#
644
- # Hold _write_lock : ensures only writer at a time
617
+ # Hold _lock : ensures only writer at a time
645
618
#
646
619
# I/O occurs while the lock is held; waiting threads will see a delay.
647
- with self ._write_lock :
620
+ with self ._lock :
648
621
try :
649
622
self ._sock .sendall (data )
650
623
except socket .error as e :
@@ -659,12 +632,12 @@ def _adjust_receive_window(self, frame_len):
659
632
"""
660
633
# Concurrency
661
634
#
662
- # Hold _write_lock ; synchronize the window manager update and the
635
+ # Hold _lock ; synchronize the window manager update and the
663
636
# subsequent potential write to the connection
664
637
#
665
638
# I/O may occur while the lock is held; waiting threads may see a
666
639
# delay.
667
- with self ._write_lock :
640
+ with self ._lock :
668
641
increment = self .window_manager ._handle_frame (frame_len )
669
642
670
643
if increment :
@@ -686,7 +659,7 @@ def _single_read(self):
686
659
# Synchronizes reading the data
687
660
#
688
661
# I/O occurs while the lock is held; waiting threads will see a delay.
689
- with self ._read_lock :
662
+ with self ._lock :
690
663
if self ._sock is None :
691
664
raise ConnectionError ('tried to read after connection close' )
692
665
self ._sock .fill ()
@@ -780,7 +753,7 @@ def _recv_cb(self, stream_id=0):
780
753
# re-acquired in the calls to self._single_read.
781
754
#
782
755
# I/O occurs while the lock is held; waiting threads will see a delay.
783
- with self ._read_lock :
756
+ with self ._lock :
784
757
log .debug ('recv for stream %d with %s already present' ,
785
758
stream_id ,
786
759
self .recent_recv_streams )
@@ -831,11 +804,11 @@ def _send_rst_frame(self, stream_id, error_code):
831
804
"""
832
805
# Concurrency
833
806
#
834
- # Hold _write_lock ; synchronize generating the reset frame and writing
807
+ # Hold _lock ; synchronize generating the reset frame and writing
835
808
# it
836
809
#
837
810
# I/O occurs while the lock is held; waiting threads will see a delay.
838
- with self ._write_lock :
811
+ with self ._lock :
839
812
with self ._conn as conn :
840
813
conn .reset_stream (stream_id , error_code = error_code )
841
814
self ._send_outstanding_data ()
0 commit comments