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

Commit 9037939

Browse files
committed
Resuse write requests
Is only one per write context
1 parent cda22c3 commit 9037939

File tree

1 file changed

+39
-8
lines changed

1 file changed

+39
-8
lines changed

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

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ public class SocketOutput : ISocketOutput
2525

2626
// This locks access to to all of the below fields
2727
private readonly object _lockObj = new object();
28+
private bool _isDisposed;
2829

2930
// The number of write operations that have been scheduled so far
3031
// but have not completed.
@@ -236,11 +237,16 @@ private void OnWriteCompleted(WriteContext write)
236237
}
237238

238239
if (_writeContexts.Count < _maxPooledWriteContexts
239-
&& write.Buffers.Count <= _maxPooledBufferQueues)
240+
&& write.Buffers.Count <= _maxPooledBufferQueues
241+
&& !_isDisposed)
240242
{
241243
write.Reset();
242244
_writeContexts.Enqueue(write);
243245
}
246+
else
247+
{
248+
write.Dispose();
249+
}
244250

245251
// Now that the while loop has completed the following invariants should hold true:
246252
Debug.Assert(_numBytesPreCompleted >= 0);
@@ -268,7 +274,21 @@ Task ISocketOutput.WriteAsync(ArraySegment<byte> buffer, bool immediate, Cancell
268274
return WriteAsync(buffer, immediate);
269275
}
270276

271-
private class WriteContext
277+
private void Dispose()
278+
{
279+
lock (_lockObj)
280+
{
281+
_isDisposed = true;
282+
283+
while (_writeContexts.Count > 0)
284+
{
285+
_writeContexts.Dequeue().Dispose();
286+
}
287+
}
288+
289+
}
290+
291+
private class WriteContext : IDisposable
272292
{
273293
public SocketOutput Self;
274294

@@ -278,13 +298,16 @@ private class WriteContext
278298

279299
public int WriteStatus;
280300
public Exception WriteError;
301+
private UvWriteReq _writeReq;
281302

282303
public int ShutdownSendStatus;
283304

284305
public WriteContext(SocketOutput self)
285306
{
286307
Self = self;
287308
Buffers = new Queue<ArraySegment<byte>>(_maxPooledBufferQueues);
309+
_writeReq = new UvWriteReq(Self._log);
310+
_writeReq.Init(Self._thread.Loop);
288311
}
289312

290313
/// <summary>
@@ -305,12 +328,9 @@ public void DoWriteIfNeeded()
305328
{
306329
buffers[i++] = buffer;
307330
}
308-
309-
var writeReq = new UvWriteReq(Self._log);
310-
writeReq.Init(Self._thread.Loop);
311-
writeReq.Write(Self._socket, new ArraySegment<ArraySegment<byte>>(buffers), (_writeReq, status, error, state) =>
331+
332+
_writeReq.Write(Self._socket, new ArraySegment<ArraySegment<byte>>(buffers), (_writeReq, status, error, state) =>
312333
{
313-
_writeReq.Dispose();
314334
var _this = (WriteContext)state;
315335
_this.WriteStatus = status;
316336
_this.WriteError = error;
@@ -348,11 +368,17 @@ public void DoShutdownIfNeeded()
348368
/// </summary>
349369
public void DoDisconnectIfNeeded()
350370
{
351-
if (SocketDisconnect == false || Self._socket.IsClosed)
371+
if (SocketDisconnect == false)
352372
{
353373
Complete();
354374
return;
355375
}
376+
else if (Self._socket.IsClosed)
377+
{
378+
Self.Dispose();
379+
Complete();
380+
return;
381+
}
356382

357383
Self._socket.Dispose();
358384
Self._log.ConnectionStop(Self._connectionId);
@@ -373,6 +399,11 @@ public void Reset()
373399
WriteError = null;
374400
ShutdownSendStatus = 0;
375401
}
402+
403+
public void Dispose()
404+
{
405+
_writeReq.Dispose();
406+
}
376407
}
377408
}
378409
}

0 commit comments

Comments
 (0)