@@ -46,9 +46,8 @@ class MplexStream(IMuxedStream):
46
46
read_deadline : int | None
47
47
write_deadline : int | None
48
48
49
+ # TODO: Add lock for read/write to avoid interleaving receiving messages?
49
50
close_lock : trio .Lock
50
- read_lock : trio .Lock
51
- write_lock : trio .Lock
52
51
53
52
# NOTE: `dataIn` is size of 8 in Go implementation.
54
53
incoming_data_channel : "trio.MemoryReceiveChannel[bytes]"
@@ -81,8 +80,6 @@ def __init__(
81
80
self .event_remote_closed = trio .Event ()
82
81
self .event_reset = trio .Event ()
83
82
self .close_lock = trio .Lock ()
84
- self .read_lock = trio .Lock ()
85
- self .write_lock = trio .Lock ()
86
83
self .incoming_data_channel = incoming_data_channel
87
84
self ._buf = bytearray ()
88
85
@@ -116,65 +113,63 @@ async def read(self, n: int | None = None) -> bytes:
116
113
:param n: number of bytes to read
117
114
:return: bytes actually read
118
115
"""
119
- async with self .read_lock :
120
- if n is not None and n < 0 :
121
- raise ValueError (
122
- "the number of bytes to read `n` must be non-negative or "
123
- f"`None` to indicate read until EOF, got n={ n } "
124
- )
125
- if self .event_reset .is_set ():
126
- raise MplexStreamReset
127
- if n is None :
128
- return await self ._read_until_eof ()
129
- if len (self ._buf ) == 0 :
130
- data : bytes
131
- # Peek whether there is data available. If yes, we just read until
132
- # there is no data, then return.
116
+ if n is not None and n < 0 :
117
+ raise ValueError (
118
+ "the number of bytes to read `n` must be non-negative or "
119
+ f"`None` to indicate read until EOF, got n={ n } "
120
+ )
121
+ if self .event_reset .is_set ():
122
+ raise MplexStreamReset
123
+ if n is None :
124
+ return await self ._read_until_eof ()
125
+ if len (self ._buf ) == 0 :
126
+ data : bytes
127
+ # Peek whether there is data available. If yes, we just read until there is
128
+ # no data, then return.
129
+ try :
130
+ data = self .incoming_data_channel .receive_nowait ()
131
+ self ._buf .extend (data )
132
+ except trio .EndOfChannel :
133
+ raise MplexStreamEOF
134
+ except trio .WouldBlock :
135
+ # We know `receive` will be blocked here. Wait for data here with
136
+ # `receive` and catch all kinds of errors here.
133
137
try :
134
- data = self .incoming_data_channel .receive_nowait ()
138
+ data = await self .incoming_data_channel .receive ()
135
139
self ._buf .extend (data )
136
140
except trio .EndOfChannel :
137
- raise MplexStreamEOF
138
- except trio .WouldBlock :
139
- # We know `receive` will be blocked here. Wait for data here with
140
- # `receive` and catch all kinds of errors here.
141
- try :
142
- data = await self .incoming_data_channel .receive ()
143
- self ._buf .extend (data )
144
- except trio .EndOfChannel :
145
- if self .event_reset .is_set ():
146
- raise MplexStreamReset
147
- if self .event_remote_closed .is_set ():
148
- raise MplexStreamEOF
149
- except trio .ClosedResourceError as error :
150
- # Probably `incoming_data_channel` is closed in `reset` when
151
- # we are waiting for `receive`.
152
- if self .event_reset .is_set ():
153
- raise MplexStreamReset
154
- raise Exception (
155
- "`incoming_data_channel` is closed but stream is not reset."
156
- "This should never happen."
157
- ) from error
158
- self ._buf .extend (self ._read_return_when_blocked ())
159
- payload = self ._buf [:n ]
160
- self ._buf = self ._buf [len (payload ) :]
161
- return bytes (payload )
141
+ if self .event_reset .is_set ():
142
+ raise MplexStreamReset
143
+ if self .event_remote_closed .is_set ():
144
+ raise MplexStreamEOF
145
+ except trio .ClosedResourceError as error :
146
+ # Probably `incoming_data_channel` is closed in `reset` when we are
147
+ # waiting for `receive`.
148
+ if self .event_reset .is_set ():
149
+ raise MplexStreamReset
150
+ raise Exception (
151
+ "`incoming_data_channel` is closed but stream is not reset. "
152
+ "This should never happen."
153
+ ) from error
154
+ self ._buf .extend (self ._read_return_when_blocked ())
155
+ payload = self ._buf [:n ]
156
+ self ._buf = self ._buf [len (payload ) :]
157
+ return bytes (payload )
162
158
163
159
async def write (self , data : bytes ) -> None :
164
160
"""
165
161
Write to stream.
166
162
167
163
:return: number of bytes written
168
164
"""
169
- async with self .write_lock :
170
- if self .event_local_closed .is_set ():
171
- raise MplexStreamClosed (f"cannot write to closed stream: data={ data !r} " )
172
- flag = (
173
- HeaderTags .MessageInitiator
174
- if self .is_initiator
175
- else HeaderTags .MessageReceiver
176
- )
177
- await self .muxed_conn .send_message (flag , data , self .stream_id )
165
+ if self .event_local_closed .is_set ():
166
+ raise MplexStreamClosed (f"cannot write to closed stream: data={ data !r} " )
167
+ flag = (
168
+ HeaderTags .MessageInitiator
169
+ if self .is_initiator
170
+ else HeaderTags .MessageReceiver
171
+ )
172
+ await self .muxed_conn .send_message (flag , data , self .stream_id )
178
173
179
174
async def close (self ) -> None :
180
175
"""
0 commit comments