@@ -9,7 +9,7 @@ namespace Sentry.Internal;
99/// Must be attempted to flush via <see cref="TryEnterFlushScope"/> when either the <see cref="Capacity"/> is reached,
1010/// or when the <see cref="_timeout"/> is exceeded.
1111/// </remarks>
12- [ DebuggerDisplay ( "Name = {Name}, Capacity = {Capacity}, Additions = {_additions}, AddCount = {AddCount}" ) ]
12+ [ DebuggerDisplay ( "Name = {Name}, Capacity = {Capacity}, Additions = {_additions}, AddCount = {AddCount}, IsDisposed = {_disposed} " ) ]
1313internal sealed class StructuredLogBatchBuffer : IDisposable
1414{
1515 private readonly SentryLog [ ] _array ;
@@ -18,9 +18,10 @@ internal sealed class StructuredLogBatchBuffer : IDisposable
1818
1919 private readonly Timer _timer ;
2020 private readonly TimeSpan _timeout ;
21-
2221 private readonly Action < StructuredLogBatchBuffer > _timeoutExceededAction ;
2322
23+ private volatile bool _disposed ;
24+
2425 /// <summary>
2526 /// Create a new buffer.
2627 /// </summary>
@@ -39,8 +40,8 @@ public StructuredLogBatchBuffer(int capacity, TimeSpan timeout, Action<Structure
3940
4041 _timer = new Timer ( OnIntervalElapsed , this , Timeout . Infinite , Timeout . Infinite ) ;
4142 _timeout = timeout ;
42-
4343 _timeoutExceededAction = timeoutExceededAction ;
44+
4445 Name = name ?? "default" ;
4546 }
4647
@@ -62,22 +63,25 @@ public StructuredLogBatchBuffer(int capacity, TimeSpan timeout, Action<Structure
6263 /// <summary>
6364 /// Number of <see cref="Add"/> operations in progress.
6465 /// </summary>
65- /// <remarks>
66- /// This property is used for debugging only.
67- /// </remarks>
6866 private int AddCount => _addLock . Count ;
6967
7068 /// <summary>
71- /// Attempt to atomically add one element to the buffer.
69+ /// Attempt to add one element to the buffer.
70+ /// Is thread-safe.
7271 /// </summary>
73- /// <param name="item">Element attempted to be added atomically .</param>
74- /// <returns>An <see cref="BatchBufferAddStatus "/> describing the result of the operation.</returns>
75- internal BatchBufferAddStatus Add ( SentryLog item )
72+ /// <param name="item">Element attempted to be added.</param>
73+ /// <returns>An <see cref="StructuredLogBatchBufferAddStatus "/> describing the result of the thread-safe operation.</returns>
74+ internal StructuredLogBatchBufferAddStatus Add ( SentryLog item )
7675 {
76+ if ( _disposed )
77+ {
78+ return StructuredLogBatchBufferAddStatus . IgnoredIsDisposed ;
79+ }
80+
7781 using var scope = _addLock . TryEnterCounterScope ( ) ;
7882 if ( ! scope . IsEntered )
7983 {
80- return BatchBufferAddStatus . IgnoredIsFlushing ;
84+ return StructuredLogBatchBufferAddStatus . IgnoredIsFlushing ;
8185 }
8286
8387 var count = Interlocked . Increment ( ref _additions ) ;
@@ -86,24 +90,24 @@ internal BatchBufferAddStatus Add(SentryLog item)
8690 {
8791 EnableTimer ( ) ;
8892 _array [ count - 1 ] = item ;
89- return BatchBufferAddStatus . AddedFirst ;
93+ return StructuredLogBatchBufferAddStatus . AddedFirst ;
9094 }
9195
9296 if ( count < _array . Length )
9397 {
9498 _array [ count - 1 ] = item ;
95- return BatchBufferAddStatus . Added ;
99+ return StructuredLogBatchBufferAddStatus . Added ;
96100 }
97101
98102 if ( count == _array . Length )
99103 {
100104 DisableTimer ( ) ;
101105 _array [ count - 1 ] = item ;
102- return BatchBufferAddStatus . AddedLast ;
106+ return StructuredLogBatchBufferAddStatus . AddedLast ;
103107 }
104108
105109 Debug . Assert ( count > _array . Length ) ;
106- return BatchBufferAddStatus . IgnoredCapacityExceeded ;
110+ return StructuredLogBatchBufferAddStatus . IgnoredCapacityExceeded ;
107111 }
108112
109113 /// <summary>
@@ -114,6 +118,11 @@ internal BatchBufferAddStatus Add(SentryLog item)
114118 /// </remarks>
115119 internal FlushScope TryEnterFlushScope ( )
116120 {
121+ if ( _disposed )
122+ {
123+ return new FlushScope ( ) ;
124+ }
125+
117126 var scope = _addLock . TryEnterLockScope ( ) ;
118127 if ( scope . IsEntered )
119128 {
@@ -132,11 +141,14 @@ private void ExitFlushScope()
132141 }
133142
134143 /// <summary>
135- /// Callback when Timer has elapsed after first item has been added.
144+ /// Callback when Timer has elapsed after first item has been added and buffer is not full yet .
136145 /// </summary>
137146 internal void OnIntervalElapsed ( object ? state )
138147 {
139- _timeoutExceededAction ( this ) ;
148+ if ( ! _disposed )
149+ {
150+ _timeoutExceededAction ( this ) ;
151+ }
140152 }
141153
142154 /// <summary>
@@ -193,21 +205,20 @@ private void Clear(int length)
193205
194206 private void EnableTimer ( )
195207 {
196- var updated = _timer . Change ( _timeout , Timeout . InfiniteTimeSpan ) ;
197- Debug . Assert ( updated , "Timer was not successfully enabled." ) ;
208+ _ = _timer . Change ( _timeout , Timeout . InfiniteTimeSpan ) ;
198209 }
199210
200211 private void DisableTimer ( )
201212 {
202- var updated = _timer . Change ( Timeout . Infinite , Timeout . Infinite ) ;
203- Debug . Assert ( updated , "Timer was not successfully disabled." ) ;
213+ _ = _timer . Change ( Timeout . Infinite , Timeout . Infinite ) ;
204214 }
205215
206216 /// <inheritdoc />
207217 public void Dispose ( )
208218 {
209219 _timer . Dispose ( ) ;
210220 _addLock . Dispose ( ) ;
221+ _disposed = true ;
211222 }
212223
213224 private static void ThrowIfLessThanTwo ( int value , string paramName )
@@ -240,7 +251,7 @@ static void ThrowNegativeOrZero(TimeSpan value, string paramName)
240251 /// A scope than ensures only a single <see cref="Flush"/> operation is in progress,
241252 /// and blocks the calling thread until all <see cref="Add"/> operations have finished.
242253 /// When <see cref="IsEntered"/> is <see langword="true"/>, no more <see cref="Add"/> can be started,
243- /// which will then return <see cref="BatchBufferAddStatus .IgnoredIsFlushing"/> immediately.
254+ /// which will then return <see cref="StructuredLogBatchBufferAddStatus .IgnoredIsFlushing"/> immediately.
244255 /// </summary>
245256 /// <remarks>
246257 /// Only <see cref="Flush"/> when scope <see cref="IsEntered"/>.
@@ -287,11 +298,12 @@ public void Dispose()
287298 }
288299}
289300
290- internal enum BatchBufferAddStatus : byte
301+ internal enum StructuredLogBatchBufferAddStatus : byte
291302{
292303 AddedFirst ,
293304 Added ,
294305 AddedLast ,
295306 IgnoredCapacityExceeded ,
296307 IgnoredIsFlushing ,
308+ IgnoredIsDisposed ,
297309}
0 commit comments