Skip to content

Commit

Permalink
ConcurrentRequestQueue - Always see queue as empty after having reach…
Browse files Browse the repository at this point in the history
…ed RequestLimit
  • Loading branch information
snakefoot committed May 26, 2019
1 parent b83d37f commit 09c087f
Showing 1 changed file with 9 additions and 10 deletions.
19 changes: 9 additions & 10 deletions src/NLog/Targets/Wrappers/ConcurrentRequestQueue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ public ConcurrentRequestQueue(int requestLimit, AsyncTargetWrapperOverflowAction
public override bool Enqueue(AsyncLogEventInfo logEventInfo)
{
long currentCount = Interlocked.Increment(ref _count);
bool queueWasEmpty = currentCount == 1; // Inserted first item in empty queue
if (currentCount > RequestLimit)
{
InternalLogger.Debug("Async queue is full");
Expand All @@ -91,18 +92,19 @@ public override bool Enqueue(AsyncLogEventInfo logEventInfo)
if (_logEventInfoQueue.TryDequeue(out var lostItem))
{
InternalLogger.Debug("Discarding one element from queue");
currentCount = Interlocked.Decrement(ref _count);
queueWasEmpty = Interlocked.Decrement(ref _count) == 1;
OnLogEventDropped(lostItem.LogEvent);
break;
}
Interlocked.Decrement(ref _count);
currentCount = Interlocked.Increment(ref _count);
currentCount = Interlocked.Read(ref _count);
queueWasEmpty = true;
} while (currentCount > RequestLimit);
}
break;
case AsyncTargetWrapperOverflowAction.Block:
{
currentCount = WaitForBelowRequestLimit();
WaitForBelowRequestLimit();
queueWasEmpty = true;
}
break;
case AsyncTargetWrapperOverflowAction.Grow:
Expand All @@ -115,10 +117,10 @@ public override bool Enqueue(AsyncLogEventInfo logEventInfo)
}
}
_logEventInfoQueue.Enqueue(logEventInfo);
return currentCount == 1; // Inserted first item in empty queue
return queueWasEmpty;
}

private long WaitForBelowRequestLimit()
private void WaitForBelowRequestLimit()
{
long currentCount;
bool lockTaken = false;
Expand All @@ -130,24 +132,21 @@ private long WaitForBelowRequestLimit()
// If yield did not help, then wait on a lock
while (currentCount > RequestLimit)
{
Interlocked.Decrement(ref _count);
InternalLogger.Debug("Blocking because the overflow action is Block...");
if (!lockTaken)
Monitor.Enter(_logEventInfoQueue);
else
Monitor.Wait(_logEventInfoQueue);
lockTaken = true;
InternalLogger.Trace("Entered critical section.");
currentCount = Interlocked.Increment(ref _count);
currentCount = Interlocked.Read(ref _count);
}
}
finally
{
if (lockTaken)
Monitor.Exit(_logEventInfoQueue);
}

return currentCount;
}

private long TrySpinWaitForLowerCount()
Expand Down

0 comments on commit 09c087f

Please sign in to comment.