Thanks to visit codestin.com
Credit goes to github.com

Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit bf58fb0

Browse files
committed
Avoid boxing Int32 result per operation
- Change BufferAsyncResult to allow storing int result, without adding another field - Use that in both SslStream and NegotiateStream to avoid boxing an int per read and write - Also rename AsyncProtocolRequest.CompleteWithError to CompleteUserWithError, to avoid confusion and keep it consistent with the other CompleteUser methods.
1 parent 411c156 commit bf58fb0

File tree

7 files changed

+76
-70
lines changed

7 files changed

+76
-70
lines changed

src/System.Net.Security/src/System/Net/BufferAsyncResult.cs

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,64 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33
// See the LICENSE file in the project root for more information.
44

5+
using System.Diagnostics;
6+
57
namespace System.Net
68
{
79
//
810
// Preserve the original request buffer & sizes for user IO requests.
911
// This is returned as an IAsyncResult to the application.
1012
//
11-
internal class BufferAsyncResult : LazyAsyncResult
13+
internal sealed class BufferAsyncResult : LazyAsyncResult
1214
{
13-
public byte[] Buffer;
14-
public int Offset;
15-
public int Count;
15+
/// <summary>Stored into LazyAsyncResult.Result to indicate a completed result.</summary>
16+
public static readonly object ResultSentinal = nameof(BufferAsyncResult) + "." + nameof(ResultSentinal);
17+
/// <summary>Stores the input count or the output result of the operation.</summary>
18+
private int _countOrResult;
19+
#if DEBUG
20+
/// <summary>true if <see cref="_countOrResult"/> backs <see cref="Int32Result"/>, false if <see cref="Count"/>.</summary>
21+
private bool _countOrResultIsResult;
22+
#endif
1623

1724
public BufferAsyncResult(object asyncObject, byte[] buffer, int offset, int count, object asyncState, AsyncCallback asyncCallback)
1825
: base(asyncObject, asyncState, asyncCallback)
1926
{
2027
Buffer = buffer;
2128
Offset = offset;
22-
Count = count;
29+
_countOrResult = count;
30+
}
31+
32+
public byte[] Buffer { get; }
33+
public int Offset { get; }
34+
public int Count
35+
{
36+
get
37+
{
38+
#if DEBUG
39+
Debug.Assert(!_countOrResultIsResult, "Trying to get count after it's already the result");
40+
#endif
41+
return _countOrResult;
42+
}
43+
}
44+
45+
public int Int32Result // Int32Result to differentiate from the base's "object Result"
46+
{
47+
get
48+
{
49+
#if DEBUG
50+
Debug.Assert(_countOrResultIsResult, "Still represents the count, not the result");
51+
Debug.Assert(ReferenceEquals(Result, ResultSentinal), "Expected the base object Result to be the sentinel");
52+
#endif
53+
return _countOrResult;
54+
}
55+
set
56+
{
57+
#if DEBUG
58+
Debug.Assert(!_countOrResultIsResult, "Should only be set when result hasn't yet been set");
59+
_countOrResultIsResult = true;
60+
#endif
61+
_countOrResult = value;
62+
}
2363
}
2464
}
2565
}

src/System.Net.Security/src/System/Net/FixedSizeReader.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ private static void ReadCallback(IAsyncResult transportResult)
151151
throw;
152152
}
153153

154-
request.CompleteWithError(e);
154+
request.CompleteUserWithError(e);
155155
}
156156
}
157157
}

src/System.Net.Security/src/System/Net/HelperAsyncResults.cs

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33
// See the LICENSE file in the project root for more information.
44

5+
using System.Diagnostics;
56
using System.Threading;
67

78
namespace System.Net
@@ -88,13 +89,7 @@ public void SetNextRequest(byte[] buffer, int offset, int count, AsyncProtocolCa
8889
_callback = callback;
8990
}
9091

91-
internal object AsyncObject
92-
{
93-
get
94-
{
95-
return UserAsyncResult.AsyncObject;
96-
}
97-
}
92+
internal object AsyncObject => UserAsyncResult.AsyncObject;
9893

9994
//
10095
// Notify protocol so a next stage could be started.
@@ -137,24 +132,18 @@ public bool MustCompleteSynchronously
137132
//
138133
// Important: This will abandon _Callback and directly notify UserAsyncResult.
139134
//
140-
internal void CompleteWithError(Exception e)
141-
{
142-
UserAsyncResult.InvokeCallback(e);
143-
}
135+
internal void CompleteUserWithError(Exception e) => UserAsyncResult.InvokeCallback(e);
144136

145-
internal void CompleteUser()
146-
{
147-
UserAsyncResult.InvokeCallback();
148-
}
137+
internal void CompleteUser() => UserAsyncResult.InvokeCallback();
149138

150-
internal void CompleteUser(object userResult)
139+
internal void CompleteUser(int userResult)
151140
{
152-
UserAsyncResult.InvokeCallback(userResult);
141+
Debug.Assert(UserAsyncResult is BufferAsyncResult, "CompleteUseR(int) may only be used with a BufferAsyncResult");
142+
var bar = (BufferAsyncResult)UserAsyncResult;
143+
bar.Int32Result = userResult;
144+
bar.InvokeCallback(BufferAsyncResult.ResultSentinal);
153145
}
154146

155-
internal bool IsUserCompleted
156-
{
157-
get { return UserAsyncResult.InternalPeekCompleted; }
158-
}
147+
internal bool IsUserCompleted => UserAsyncResult.InternalPeekCompleted;
159148
}
160149
}

src/System.Net.Security/src/System/Net/Security/InternalNegotiateStream.cs

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -216,10 +216,7 @@ private int ProcessRead(byte[] buffer, int offset, int count, AsyncProtocolReque
216216
Buffer.BlockCopy(InternalBuffer, InternalOffset, buffer, offset, copyBytes);
217217
DecrementInternalBufferCount(copyBytes);
218218
}
219-
if (asyncRequest != null)
220-
{
221-
asyncRequest.CompleteUser((object)copyBytes);
222-
}
219+
asyncRequest?.CompleteUser(copyBytes);
223220
return copyBytes;
224221
}
225222

@@ -283,10 +280,7 @@ private int StartFrameBody(int readBytes, byte[] buffer, int offset, int count,
283280
if (readBytes == 0)
284281
{
285282
//EOF
286-
if (asyncRequest != null)
287-
{
288-
asyncRequest.CompleteUser((object)0);
289-
}
283+
asyncRequest?.CompleteUser(0);
290284
return 0;
291285
}
292286

@@ -368,10 +362,7 @@ private int ProcessFrameBody(int readBytes, byte[] buffer, int offset, int count
368362
// This will adjust both the remaining internal buffer count and the offset.
369363
DecrementInternalBufferCount(readBytes);
370364

371-
if (asyncRequest != null)
372-
{
373-
asyncRequest.CompleteUser((object)readBytes);
374-
}
365+
asyncRequest?.CompleteUser(readBytes);
375366

376367
return readBytes;
377368
}
@@ -410,7 +401,7 @@ private static void WriteCallback(IAsyncResult transportResult)
410401
throw;
411402
}
412403

413-
asyncRequest.CompleteWithError(e);
404+
asyncRequest.CompleteUserWithError(e);
414405
}
415406
}
416407

@@ -444,7 +435,7 @@ private static void ReadCallback(AsyncProtocolRequest asyncRequest)
444435
throw;
445436
}
446437

447-
asyncRequest.CompleteWithError(e);
438+
asyncRequest.CompleteUserWithError(e);
448439
}
449440
}
450441
}

src/System.Net.Security/src/System/Net/Security/NegotiateStream.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -625,7 +625,7 @@ public override int EndRead(IAsyncResult asyncResult)
625625
throw new IOException(SR.net_io_read, (Exception)bufferResult.Result);
626626
}
627627

628-
return (int)bufferResult.Result;
628+
return bufferResult.Int32Result;
629629
#if DEBUG
630630
}
631631
#endif

src/System.Net.Security/src/System/Net/Security/SslState.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1441,7 +1441,7 @@ private void FinishHandshake(Exception e, AsyncProtocolRequest asyncRequest)
14411441
{
14421442
if (e != null)
14431443
{
1444-
asyncRequest.CompleteWithError(e);
1444+
asyncRequest.CompleteUserWithError(e);
14451445
}
14461446
else
14471447
{
@@ -1725,7 +1725,7 @@ private void AsyncResumeHandshake(object state)
17251725
}
17261726
catch (Exception e)
17271727
{
1728-
request.CompleteWithError(e);
1728+
request.CompleteUserWithError(e);
17291729
}
17301730
}
17311731

src/System.Net.Security/src/System/Net/Security/SslStreamInternal.cs

Lines changed: 12 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ internal int EndRead(IAsyncResult asyncResult)
169169
throw new IOException(SR.net_io_read, (Exception)bufferResult.Result);
170170
}
171171

172-
return (int)bufferResult.Result;
172+
return bufferResult.Int32Result;
173173
}
174174

175175
internal IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback asyncCallback, object asyncState)
@@ -495,7 +495,7 @@ private void StartWriting(byte[] buffer, int offset, int count, AsyncProtocolReq
495495
//
496496
// Combined sync/async read method. For sync request asyncRequest==null.
497497
//
498-
private int ProcessRead(byte[] buffer, int offset, int count, LazyAsyncResult asyncResult)
498+
private int ProcessRead(byte[] buffer, int offset, int count, BufferAsyncResult asyncResult)
499499
{
500500
ValidateParameters(buffer, offset, count);
501501

@@ -522,9 +522,7 @@ private int ProcessRead(byte[] buffer, int offset, int count, LazyAsyncResult as
522522
SkipBytes(copyBytes);
523523
}
524524

525-
if (asyncRequest != null) {
526-
asyncRequest.CompleteUser((object) copyBytes);
527-
}
525+
asyncRequest?.CompleteUser(copyBytes);
528526

529527
return copyBytes;
530528
}
@@ -580,10 +578,7 @@ private int StartReading(byte[] buffer, int offset, int count, AsyncProtocolRequ
580578

581579
if (copyBytes != -1)
582580
{
583-
if (asyncRequest != null)
584-
{
585-
asyncRequest.CompleteUser((object)copyBytes);
586-
}
581+
asyncRequest?.CompleteUser(copyBytes);
587582

588583
return copyBytes;
589584
}
@@ -633,10 +628,7 @@ private int StartFrameBody(int readBytes, byte[] buffer, int offset, int count,
633628
{
634629
//EOF : Reset the buffer as we did not read anything into it.
635630
SkipBytes(InternalBufferCount);
636-
if (asyncRequest != null)
637-
{
638-
asyncRequest.CompleteUser((object)0);
639-
}
631+
asyncRequest?.CompleteUser(0);
640632

641633
return 0;
642634
}
@@ -728,10 +720,7 @@ private int ProcessFrameBody(int readBytes, byte[] buffer, int offset, int count
728720
SkipBytes(readBytes);
729721

730722
_sslState.FinishRead(null);
731-
if (asyncRequest != null)
732-
{
733-
asyncRequest.CompleteUser((object)readBytes);
734-
}
723+
asyncRequest?.CompleteUser(readBytes);
735724

736725
return readBytes;
737726
}
@@ -752,10 +741,7 @@ private int ProcessReadErrorCode(SecurityStatusPal status, byte[] buffer, int of
752741
if (message.CloseConnection)
753742
{
754743
_sslState.FinishRead(null);
755-
if (asyncRequest != null)
756-
{
757-
asyncRequest.CompleteUser((object)0);
758-
}
744+
asyncRequest?.CompleteUser(0);
759745

760746
return 0;
761747
}
@@ -801,7 +787,7 @@ private static void WriteCallback(IAsyncResult transportResult)
801787
}
802788

803789
sslStream._sslState.FinishWrite();
804-
asyncRequest.CompleteWithError(e);
790+
asyncRequest.CompleteUserWithError(e);
805791
}
806792
}
807793

@@ -823,7 +809,7 @@ private static void ResumeAsyncReadCallback(AsyncProtocolRequest request)
823809
}
824810

825811
((SslStreamInternal)request.AsyncObject)._sslState.FinishRead(null);
826-
request.CompleteWithError(e);
812+
request.CompleteUserWithError(e);
827813
}
828814
}
829815

@@ -845,7 +831,7 @@ private static void ResumeAsyncWriteCallback(AsyncProtocolRequest asyncRequest)
845831
}
846832

847833
((SslStreamInternal)asyncRequest.AsyncObject)._sslState.FinishWrite();
848-
asyncRequest.CompleteWithError(e);
834+
asyncRequest.CompleteUserWithError(e);
849835
}
850836
}
851837

@@ -869,7 +855,7 @@ private static void ReadHeaderCallback(AsyncProtocolRequest asyncRequest)
869855
throw;
870856
}
871857

872-
asyncRequest.CompleteWithError(e);
858+
asyncRequest.CompleteUserWithError(e);
873859
}
874860
}
875861

@@ -893,7 +879,7 @@ private static void ReadFrameCallback(AsyncProtocolRequest asyncRequest)
893879
throw;
894880
}
895881

896-
asyncRequest.CompleteWithError(e);
882+
asyncRequest.CompleteUserWithError(e);
897883
}
898884
}
899885
}

0 commit comments

Comments
 (0)