-
Notifications
You must be signed in to change notification settings - Fork 4.9k
SslStream Improvements for Unix Performance #22998
Changes from 1 commit
4b4b72c
4079b92
1fa274a
d5fc983
7bbcc3d
dd8fae2
7c51afe
7080b69
860bba1
6b19a38
7f7f47a
0be51ac
4694662
5f4e2bf
293ea41
d83a091
05b412b
56a7e43
e6dd27e
93e0ad9
7904f68
bebfc15
6033a15
f4c0005
b4d2301
f4dbc39
0e78e71
3014c47
a47874f
fb87ba4
dcbed7e
3ec53c6
3c1d3bd
f6dcc55
0a27d81
bc46993
5ba0c75
a049480
fc6f327
8fd60cc
f51c9e8
03da084
172a1de
8249c15
5e97bf7
f8e86a6
9a800a3
90eb0f7
3f35c68
155e8e9
e3f1577
c67a9e2
a1ea5b5
354a992
4a1734b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
…ate errors
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -53,7 +53,11 @@ internal SslStreamInternal(SslState sslState) | |
|
||
_decryptedBytesOffset = 0; | ||
_decryptedBytesCount = 0; | ||
_freeBufferAction = (_, buffer) => FreeBuffer((byte[])buffer); | ||
_freeBufferAction = (task, buffer) => | ||
{ | ||
FreeBuffer((byte[])buffer); | ||
task.GetAwaiter().GetResult(); // propagate any exception | ||
}; | ||
} | ||
|
||
// If we have a read buffer from the pinnable cache, return it. | ||
|
@@ -415,14 +419,15 @@ private void StartWriting(byte[] buffer, int offset, int count, AsyncProtocolReq | |
{ | ||
// Prepare for the next request. | ||
asyncRequest.SetNextRequest(buffer, offset + chunkBytes, count - chunkBytes, s_resumeAsyncWriteCallback); | ||
Task t = _sslState.InnerStream.WriteAsync(outBuffer, 0, encryptedBytes) | ||
.ContinueWith(_freeBufferAction, outBuffer); | ||
Task t = _sslState.InnerStream.WriteAsync(outBuffer, 0, encryptedBytes); | ||
if (t.IsCompleted) | ||
{ | ||
FreeBuffer(outBuffer); | ||
t.GetAwaiter().GetResult(); | ||
} | ||
else | ||
{ | ||
t = t.ContinueWith(_freeBufferAction, outBuffer, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default); | ||
IAsyncResult ar = TaskToApm.Begin(t, s_writeCallback, asyncRequest); | ||
if (!ar.CompletedSynchronously) | ||
{ | ||
|
@@ -434,8 +439,14 @@ private void StartWriting(byte[] buffer, int offset, int count, AsyncProtocolReq | |
} | ||
else | ||
{ | ||
_sslState.InnerStream.Write(outBuffer, 0, encryptedBytes); | ||
FreeBuffer(outBuffer); | ||
try | ||
{ | ||
_sslState.InnerStream.Write(outBuffer, 0, encryptedBytes); | ||
} | ||
finally | ||
{ | ||
FreeBuffer(outBuffer); | ||
} | ||
} | ||
|
||
offset += chunkBytes; | ||
|
@@ -447,11 +458,7 @@ private void StartWriting(byte[] buffer, int offset, int count, AsyncProtocolReq | |
} while (count != 0); | ||
|
||
} | ||
|
||
if (asyncRequest != null) | ||
{ | ||
asyncRequest.CompleteUser(); | ||
} | ||
asyncRequest?.CompleteUser(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @stephentoub I have narrowed the issue down. It seems that it is nothing to do with the continuation/free up above. The issue is around calling asyncRequest.CompleteUser() on the current thread. So ~180k rps with the code as it stands and 256 connections (24 core/48 thread server) Task.Run(() => asyncRequest?.CompleteUser()); This is only effecting Unix, to me it seems like a contention issue because the RPS scales up to ~10 connections and then slowly goes down from there unless you put in a Task.Run(). Looking at it, could it be something in the lazy result? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. CompleteUser is basically just calling the user callback. There shouldn't be any contention in the CompleteUser call itself (though of course, there could be). The main difference here is likely something in the user code. To test this, you could add Task.Run to the user code so that the user callback will be enqueued, instead of run immediately, and see if that makes any difference. Which test are you seeing this with? I'm not sure quite what the user's callback will be doing in this case. |
||
} | ||
|
||
private void FreeBuffer(byte[] buffer) | ||
|
||
|
@@ -814,7 +821,8 @@ private int ProcessFrameBody(int readBytes, byte[] buffer, int offset, int count | |
private int ProcessReadErrorCode(SecurityStatusPal status, AsyncProtocolRequest asyncRequest, byte[] extraBuffer) | ||
{ | ||
ProtocolToken message = new ProtocolToken(null, status); | ||
if (NetEventSource.IsEnabled) NetEventSource.Info(null, $"***Processing an error Status = {message.Status}"); | ||
if (NetEventSource.IsEnabled) | ||
NetEventSource.Info(null, $"***Processing an error Status = {message.Status}"); | ||
|
||
if (message.Renegotiate) | ||
{ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How is this going to compile? :)