@@ -14,11 +14,12 @@ namespace System.Net
14
14
{
15
15
internal sealed class SafeDeleteSslContext : SafeDeleteContext
16
16
{
17
+ private const int InitialBufferSize = 2048 ;
17
18
private SafeSslHandle _sslContext ;
18
19
private Interop . AppleCrypto . SSLReadFunc _readCallback ;
19
20
private Interop . AppleCrypto . SSLWriteFunc _writeCallback ;
20
- private Queue < byte > _fromConnection = new Queue < byte > ( ) ;
21
- private Queue < byte > _toConnection = new Queue < byte > ( ) ;
21
+ private ArrayBuffer _inputBuffer = new ArrayBuffer ( InitialBufferSize ) ;
22
+ private ArrayBuffer _outputBuffer = new ArrayBuffer ( InitialBufferSize ) ;
22
23
23
24
public SafeSslHandle SslContext => _sslContext ;
24
25
@@ -141,10 +142,12 @@ protected override void Dispose(bool disposing)
141
142
{
142
143
if ( disposing )
143
144
{
144
- if ( null != _sslContext )
145
+ SafeSslHandle sslContext = _sslContext ;
146
+ if ( null != sslContext )
145
147
{
146
- _sslContext . Dispose ( ) ;
147
- _sslContext = null ! ;
148
+ _inputBuffer . Dispose ( ) ;
149
+ _outputBuffer . Dispose ( ) ;
150
+ sslContext . Dispose ( ) ;
148
151
}
149
152
}
150
153
@@ -153,18 +156,15 @@ protected override void Dispose(bool disposing)
153
156
154
157
private unsafe int WriteToConnection ( void * connection , byte * data , void * * dataLength )
155
158
{
156
- ulong toWrite = ( ulong ) * dataLength ;
157
- byte * readFrom = data ;
159
+ ulong length = ( ulong ) * dataLength ;
160
+ Debug . Assert ( length <= int . MaxValue ) ;
158
161
159
- lock ( _toConnection )
160
- {
161
- while ( toWrite > 0 )
162
- {
163
- _toConnection . Enqueue ( * readFrom ) ;
164
- readFrom ++ ;
165
- toWrite -- ;
166
- }
167
- }
162
+ int toWrite = ( int ) length ;
163
+ var inputBuffer = new ReadOnlySpan < byte > ( data , toWrite ) ;
164
+
165
+ _outputBuffer . EnsureAvailableSpace ( toWrite ) ;
166
+ inputBuffer . CopyTo ( _outputBuffer . AvailableSpan ) ;
167
+ _outputBuffer . Commit ( toWrite ) ;
168
168
169
169
// Since we can enqueue everything, no need to re-assign *dataLength.
170
170
const int noErr = 0 ;
@@ -175,78 +175,51 @@ private unsafe int ReadFromConnection(void* connection, byte* data, void** dataL
175
175
{
176
176
const int noErr = 0 ;
177
177
const int errSSLWouldBlock = - 9803 ;
178
-
179
178
ulong toRead = ( ulong ) * dataLength ;
180
179
181
180
if ( toRead == 0 )
182
181
{
183
-
184
182
return noErr ;
185
183
}
186
184
187
185
uint transferred = 0 ;
188
186
189
- lock ( _fromConnection )
187
+ if ( _inputBuffer . ActiveLength == 0 )
190
188
{
189
+ * dataLength = ( void * ) 0 ;
190
+ return errSSLWouldBlock ;
191
+ }
191
192
192
- if ( _fromConnection . Count == 0 )
193
- {
194
-
195
- * dataLength = ( void * ) 0 ;
196
- return errSSLWouldBlock ;
197
- }
193
+ int limit = Math . Min ( ( int ) toRead , _inputBuffer . ActiveLength ) ;
198
194
199
- byte * writePos = data ;
200
-
201
- while ( transferred < toRead && _fromConnection . Count > 0 )
202
- {
203
- * writePos = _fromConnection . Dequeue ( ) ;
204
- writePos ++ ;
205
- transferred ++ ;
206
- }
207
- }
195
+ _inputBuffer . ActiveSpan . Slice ( 0 , limit ) . CopyTo ( new Span < byte > ( data , limit ) ) ;
196
+ _inputBuffer . Discard ( limit ) ;
197
+ transferred = ( uint ) limit ;
208
198
209
199
* dataLength = ( void * ) transferred ;
210
200
return noErr ;
211
201
}
212
202
213
- internal void Write ( byte [ ] buf , int offset , int count )
214
- {
215
- Debug . Assert ( buf != null ) ;
216
- Debug . Assert ( offset >= 0 ) ;
217
- Debug . Assert ( count >= 0 ) ;
218
- Debug . Assert ( count <= buf . Length - offset ) ;
219
-
220
- Write ( buf . AsSpan ( offset , count ) ) ;
221
- }
222
-
223
203
internal void Write ( ReadOnlySpan < byte > buf )
224
204
{
225
- lock ( _fromConnection )
226
- {
227
- foreach ( byte b in buf )
228
- {
229
- _fromConnection . Enqueue ( b ) ;
230
- }
231
- }
205
+ _inputBuffer . EnsureAvailableSpace ( buf . Length ) ;
206
+ buf . CopyTo ( _inputBuffer . AvailableSpan ) ;
207
+ _inputBuffer . Commit ( buf . Length ) ;
232
208
}
233
209
234
- internal int BytesReadyForConnection => _toConnection . Count ;
210
+ internal int BytesReadyForConnection => _outputBuffer . ActiveLength ;
235
211
236
212
internal byte [ ] ? ReadPendingWrites ( )
237
213
{
238
- lock ( _toConnection )
214
+ if ( _outputBuffer . ActiveLength == 0 )
239
215
{
240
- if ( _toConnection . Count == 0 )
241
- {
242
- return null ;
243
- }
216
+ return null ;
217
+ }
244
218
245
- byte [ ] data = _toConnection . ToArray ( ) ;
246
- _toConnection . Clear ( ) ;
219
+ byte [ ] buffer = _outputBuffer . ActiveSpan . ToArray ( ) ;
220
+ _outputBuffer . Discard ( _outputBuffer . ActiveLength ) ;
247
221
248
- return data ;
249
- }
222
+ return buffer ;
250
223
}
251
224
252
225
internal int ReadPendingWrites ( byte [ ] buf , int offset , int count )
@@ -256,17 +229,12 @@ internal int ReadPendingWrites(byte[] buf, int offset, int count)
256
229
Debug . Assert ( count >= 0 ) ;
257
230
Debug . Assert ( count <= buf . Length - offset ) ;
258
231
259
- lock ( _toConnection )
260
- {
261
- int limit = Math . Min ( count , _toConnection . Count ) ;
232
+ int limit = Math . Min ( count , _outputBuffer . ActiveLength ) ;
262
233
263
- for ( int i = 0 ; i < limit ; i ++ )
264
- {
265
- buf [ offset + i ] = _toConnection . Dequeue ( ) ;
266
- }
234
+ _outputBuffer . ActiveSpan . Slice ( 0 , limit ) . CopyTo ( new Span < byte > ( buf , offset , limit ) ) ;
235
+ _outputBuffer . Discard ( limit ) ;
267
236
268
- return limit ;
269
- }
237
+ return limit ;
270
238
}
271
239
272
240
private static readonly SslProtocols [ ] s_orderedSslProtocols = new SslProtocols [ 5 ]
0 commit comments