Skip to content
This repository was archived by the owner on Dec 18, 2018. It is now read-only.

Commit 4746d28

Browse files
committed
Initalize SocketOutput Queues, Reuse WriteContexts
1 parent dca9d60 commit 4746d28

File tree

1 file changed

+38
-9
lines changed

1 file changed

+38
-9
lines changed

src/Microsoft.AspNet.Server.Kestrel/Http/SocketOutput.cs

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ public class SocketOutput : ISocketOutput
1515
{
1616
private const int _maxPendingWrites = 3;
1717
private const int _maxBytesPreCompleted = 65536;
18+
private const int _maxPooledWriteContexts = 16;
1819

1920
private readonly KestrelThread _thread;
2021
private readonly UvStreamHandle _socket;
@@ -32,14 +33,16 @@ public class SocketOutput : ISocketOutput
3233
private Exception _lastWriteError;
3334
private WriteContext _nextWriteContext;
3435
private readonly Queue<TaskCompletionSource<object>> _tasksPending;
36+
private readonly Queue<WriteContext> _writeContexts;
3537

3638
public SocketOutput(KestrelThread thread, UvStreamHandle socket, long connectionId, IKestrelTrace log)
3739
{
3840
_thread = thread;
3941
_socket = socket;
4042
_connectionId = connectionId;
4143
_log = log;
42-
_tasksPending = new Queue<TaskCompletionSource<object>>();
44+
_tasksPending = new Queue<TaskCompletionSource<object>>(16);
45+
_writeContexts = new Queue<WriteContext>(_maxPooledWriteContexts);
4346
}
4447

4548
public Task WriteAsync(
@@ -63,7 +66,14 @@ public Task WriteAsync(
6366
{
6467
if (_nextWriteContext == null)
6568
{
66-
_nextWriteContext = new WriteContext(this);
69+
if (_writeContexts.Count > 0)
70+
{
71+
_nextWriteContext = _writeContexts.Dequeue();
72+
}
73+
else
74+
{
75+
_nextWriteContext = new WriteContext(this);
76+
}
6777
}
6878

6979
if (buffer.Array != null)
@@ -172,13 +182,13 @@ private void WriteAllPending()
172182
}
173183

174184
// This is called on the libuv event loop
175-
private void OnWriteCompleted(Queue<ArraySegment<byte>> writtenBuffers, int status, Exception error)
185+
private void OnWriteCompleted(WriteContext write)
176186
{
177-
_log.ConnectionWriteCallback(_connectionId, status);
187+
var status = write.WriteStatus;
178188

179189
lock (_lockObj)
180190
{
181-
_lastWriteError = error;
191+
_lastWriteError = write.WriteError;
182192

183193
if (_nextWriteContext != null)
184194
{
@@ -189,7 +199,7 @@ private void OnWriteCompleted(Queue<ArraySegment<byte>> writtenBuffers, int stat
189199
_writesPending--;
190200
}
191201

192-
foreach (var writeBuffer in writtenBuffers)
202+
foreach (var writeBuffer in write.Buffers)
193203
{
194204
// _numBytesPreCompleted can temporarily go negative in the event there are
195205
// completed writes that we haven't triggered callbacks for yet.
@@ -208,24 +218,33 @@ private void OnWriteCompleted(Queue<ArraySegment<byte>> writtenBuffers, int stat
208218
_numBytesPreCompleted += bytesToWrite;
209219
bytesLeftToBuffer -= bytesToWrite;
210220

211-
if (error == null)
221+
if (write.WriteError == null)
212222
{
213223
ThreadPool.QueueUserWorkItem(
214224
(o) => ((TaskCompletionSource<object>)o).SetResult(null),
215225
tcs);
216226
}
217227
else
218228
{
229+
var error = write.WriteError;
219230
// error is closure captured
220231
ThreadPool.QueueUserWorkItem(
221232
(o) => ((TaskCompletionSource<object>)o).SetException(error),
222233
tcs);
223234
}
224235
}
225236

237+
if (_writeContexts.Count < _maxPooledWriteContexts)
238+
{
239+
write.Reset();
240+
_writeContexts.Enqueue(write);
241+
}
242+
226243
// Now that the while loop has completed the following invariants should hold true:
227244
Debug.Assert(_numBytesPreCompleted >= 0);
228245
}
246+
247+
_log.ConnectionWriteCallback(_connectionId, status);
229248
}
230249

231250
void ISocketOutput.Write(ArraySegment<byte> buffer, bool immediate)
@@ -263,7 +282,7 @@ private class WriteContext
263282
public WriteContext(SocketOutput self)
264283
{
265284
Self = self;
266-
Buffers = new Queue<ArraySegment<byte>>();
285+
Buffers = new Queue<ArraySegment<byte>>(8);
267286
}
268287

269288
/// <summary>
@@ -340,7 +359,17 @@ public void DoDisconnectIfNeeded()
340359

341360
public void Complete()
342361
{
343-
Self.OnWriteCompleted(Buffers, WriteStatus, WriteError);
362+
Self.OnWriteCompleted(this);
363+
}
364+
365+
public void Reset()
366+
{
367+
Buffers.Clear();
368+
SocketDisconnect = false;
369+
SocketShutdownSend = false;
370+
WriteStatus = 0;
371+
WriteError = null;
372+
ShutdownSendStatus = 0;
344373
}
345374
}
346375
}

0 commit comments

Comments
 (0)