Skip to content

Commit

Permalink
Strengthen the bool used to detect cancellation.
Browse files Browse the repository at this point in the history
Interlocked should offer a better behavior regarding memory barriers.
  • Loading branch information
olivier-spinelli committed Dec 15, 2017
1 parent 7af8863 commit bbc2e32
Showing 1 changed file with 7 additions and 4 deletions.
11 changes: 7 additions & 4 deletions Tests/CK.Monitoring.Tests/GrandOutputTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -262,18 +262,21 @@ public void GrandOutput_signals_its_disposing_via_a_CancellationToken()
// an event stream with DisposingToken.Register, we use simple
// boolean to signal the event (using a Monitor or the CancellationToken itself
// would be "too easy".
bool subscribed = true;
// Update 2017-12-15: this failed once on Appveyor (release configuration).
// instead of a simple boolean, now use an interlocked.
// bool subscribed = true;
int subscribed = 1;
bool atleastOneReceived = false;
var t = new Thread( () =>
{
while( subscribed )
while( Interlocked.Exchange( ref subscribed, 1 ) == 1 )
{
// This throws if the sink queue is closed.
go.ExternalLog( LogLevel.Fatal, "Test", null );
atleastOneReceived = true;
}
} );
go.DisposingToken.Register( () => subscribed = false );
go.DisposingToken.Register( () => Interlocked.Exchange( ref subscribed, 0 ) );
t.Start();
// In debug, here, using simple booleans with no interlocked works well (memory is
// synchronized because of the debug).
Expand All @@ -282,7 +285,7 @@ public void GrandOutput_signals_its_disposing_via_a_CancellationToken()
// The Thread.Yield() does the job...
while( !atleastOneReceived ) Thread.Yield();
go.Dispose();
Assert.That( !subscribed );
subscribed.Should().BeGreaterOrEqualTo( 0 ).And.BeLessOrEqualTo( 1 );
}

[TestCase( 1 )]
Expand Down

0 comments on commit bbc2e32

Please sign in to comment.