@@ -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