Skip to content

Commit 267d29e

Browse files
snakefoot304NotModified
authored andcommitted
BufferingTargetWrapper - Avoid Timer starvation when SlidingTimeout = true
1 parent 458feb4 commit 267d29e

File tree

2 files changed

+24
-6
lines changed

2 files changed

+24
-6
lines changed

src/NLog/Common/LogEventInfoBuffer.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,15 @@ public LogEventInfoBuffer(int size, bool growAsNeeded, int growLimit)
6565
}
6666

6767
/// <summary>
68-
/// Gets the number of items in the array.
68+
/// Gets the capacity of the buffer
6969
/// </summary>
7070
public int Size => _buffer.Length;
7171

72+
/// <summary>
73+
/// Gets the number of items in the buffer
74+
/// </summary>
75+
internal int Count { get { lock (_lockObject) return _count; } }
76+
7277
/// <summary>
7378
/// Adds the specified log event to the buffer.
7479
/// </summary>

src/NLog/Targets/Wrappers/BufferingTargetWrapper.cs

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -187,10 +187,7 @@ protected override void CloseTarget()
187187
_flushTimer = null;
188188
if (currentTimer.WaitForDispose(TimeSpan.FromSeconds(1)))
189189
{
190-
lock (_lockObject)
191-
{
192-
WriteEventsInBuffer("Closing Target");
193-
}
190+
WriteEventsInBuffer("Closing Target");
194191
}
195192
}
196193

@@ -228,15 +225,24 @@ protected override void Write(AsyncLogEventInfo logEvent)
228225

229226
private void FlushCallback(object state)
230227
{
228+
bool lockTaken = false;
229+
231230
try
232231
{
233-
lock (_lockObject)
232+
int timeoutMilliseconds = Math.Min(FlushTimeout / 2, 100);
233+
lockTaken = Monitor.TryEnter(_lockObject, timeoutMilliseconds);
234+
if (lockTaken)
234235
{
235236
if (_flushTimer == null)
236237
return;
237238

238239
WriteEventsInBuffer(null);
239240
}
241+
else
242+
{
243+
if (_buffer.Count > 0)
244+
_flushTimer?.Change(FlushTimeout, -1); // Schedule new retry timer
245+
}
240246
}
241247
catch (Exception exception)
242248
{
@@ -247,6 +253,13 @@ private void FlushCallback(object state)
247253
throw; // Throwing exceptions here will crash the entire application (.NET 2.0 behavior)
248254
}
249255
}
256+
finally
257+
{
258+
if (lockTaken)
259+
{
260+
Monitor.Exit(_lockObject);
261+
}
262+
}
250263
}
251264

252265
private void WriteEventsInBuffer(string reason)

0 commit comments

Comments
 (0)