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

Commit 82e1218

Browse files
committed
Lower Thread Post contention
1 parent 24e5f64 commit 82e1218

1 file changed

Lines changed: 17 additions & 17 deletions

File tree

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

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public class SocketOutput : ISocketOutput
1616
{
1717
public const int MaxPooledWriteReqs = 1024;
1818

19-
private const int _maxPendingWrites = 3;
19+
//private const int _maxPendingWrites = 3;
2020
private const int _maxBytesPreCompleted = 65536;
2121
private const int _initialTaskQueues = 64;
2222
private const int _maxPooledWriteContexts = 32;
@@ -41,7 +41,7 @@ public class SocketOutput : ISocketOutput
4141

4242
// The number of write operations that have been scheduled so far
4343
// but have not completed.
44-
private int _writesPending = 0;
44+
//private int _writesPending = 0;
4545
private int _numBytesPreCompleted = 0;
4646
private Exception _lastWriteError;
4747
private WriteContext _nextWriteContext;
@@ -50,6 +50,8 @@ public class SocketOutput : ISocketOutput
5050
private readonly Queue<WriteContext> _writeContextPool;
5151
private readonly Queue<UvWriteReq> _writeReqPool;
5252

53+
private int _writePending = 0;
54+
5355
private readonly object _contextLock = new object();
5456
private readonly object _taskQueueLock = new object();
5557

@@ -160,16 +162,16 @@ public unsafe Task WriteAsync(
160162
if (number > 10)
161163
{
162164
number = 0;
163-
ScheduleWrite();
164-
Interlocked.Increment(ref _writesPending);
165+
scheduleWrite = true;
165166
}
166-
else if (Interlocked.Increment(ref _writesPending) < _maxPendingWrites && immediate)
167+
else if (immediate)
167168
{
168-
ScheduleWrite();
169+
scheduleWrite = true;
169170
}
170-
else
171+
172+
if (scheduleWrite)
171173
{
172-
Interlocked.Decrement(ref _writesPending);
174+
ScheduleWrite();
173175
}
174176

175177
// Return TaskCompletionSource's Task if set, otherwise completed Task
@@ -259,17 +261,20 @@ private static void ReturnBlocks(MemoryPoolBlock2 block)
259261

260262
private void ScheduleWrite()
261263
{
262-
_thread.Post(_this => _this.WriteAllPending(), this);
264+
if (Interlocked.CompareExchange(ref _writePending, 1, 0) == 0)
265+
{
266+
_thread.Post(_this => _this.WriteAllPending(), this);
267+
}
263268
}
264269

265270
// This is called on the libuv event loop
266271
private void WriteAllPending()
267272
{
273+
Volatile.Write(ref _writePending, 0);
268274
var writingContext = Interlocked.Exchange(ref _nextWriteContext, null);
269275

270276
if (writingContext == null)
271277
{
272-
Interlocked.Decrement(ref _writesPending);
273278
return;
274279
}
275280

@@ -279,8 +284,6 @@ private void WriteAllPending()
279284
}
280285
catch
281286
{
282-
Interlocked.Decrement(ref _writesPending);
283-
284287
throw;
285288
}
286289
}
@@ -308,10 +311,6 @@ private void OnWriteCompleted(WriteContext writeContext)
308311
{
309312
scheduleWrite = true;
310313
}
311-
else
312-
{
313-
Interlocked.Decrement(ref _writesPending);
314-
}
315314

316315
// _numBytesPreCompleted can temporarily go negative in the event there are
317316
// completed writes that we haven't triggered callbacks for yet.
@@ -351,7 +350,7 @@ private void OnWriteCompleted(WriteContext writeContext)
351350

352351
_log.ConnectionWriteCallback(_connectionId, status);
353352

354-
if (scheduleWrite)
353+
if (scheduleWrite || _nextWriteContext != null)
355354
{
356355
ScheduleWrite();
357356
}
@@ -590,6 +589,7 @@ private static void ReturnWrittenBlocks(MemoryPoolBlock2 block)
590589

591590
private void LockWrite()
592591
{
592+
593593
var head = Self._head;
594594
var tail = Self._tail;
595595

0 commit comments

Comments
 (0)