Skip to content

Conversation

danielcweber
Copy link
Collaborator

This is part of a a two part fix for #768. Dispose.Create has been inlined in 6ecc899, which, for RefCount, will lead to garbage if Sink.Dispose is called multiple times. This PR makes Sink.Dispose a nop from the second call on.

Note: This is not enough to fix #768, although the expectation of the OP about the behaviour is incorrect, there is another bug that will be fixed in a following PR.

@@ -25,12 +26,16 @@ protected Sink(IObserver<TTarget> observer)

public void Dispose()
{
Dispose(true);
if (_observer != NopObserver<TTarget>.Instance && Interlocked.Exchange(ref _observer, NopObserver<TTarget>.Instance) != NopObserver<TTarget>.Instance)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@akarnokd Check first and then exchange is the more efficient way to go I guess?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It has slightly more overhead when the method is called only once (mainly due to targeting the same address and causing a data dependency). Its benefits show when 3+ calls are typical. In our case, we'd expect typically 1 call, sometimes two so the Interlocked.Exchange should suffice and should be practically equivalent to the original volatile field store (they both are usually implemented as LOCK XCHG or MOV + LOCK XADD stack[0], 0).

… expected calls (< 3), the benefit will not show.
@danielcweber danielcweber merged commit 42fa781 into dotnet:master Jul 6, 2018
@danielcweber danielcweber deleted the MakeSinkDisposableIdempotent branch July 6, 2018 08:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Multiple subscriptions if using .Publish().RefCount() in 4.0.0
2 participants