-
Notifications
You must be signed in to change notification settings - Fork 751
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
4.x: Rework & fix SkipUntil with lock-free methods #551
Conversation
{ | ||
if (_forward) | ||
_parent.ForwardOnNext(value); | ||
if (Interlocked.CompareExchange(ref _halfSerializer, 1, 0) == 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would Interlocked.Increment work as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interlocked has to force a new value so it is more expensive in contended cases whereas CAS is generally cheaper, especially on the weaker platforms where increment may be actually implemented as a CAS loop. Here, there is no need to loop.
Merging, I would really like to see that halfserializer-pattern generalized (static methods etc) |
I'll post a PR with additional toolsets. |
sourceSubscription, | ||
otherSubscription | ||
); | ||
Disposable.TrySetSingle(ref _otherDisposable, parent._other.Subscribe(new OtherObserver(this))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I missed those before merging, this will for now but it should probably be SetSingle (i.e. throw when already set).
This PR reimplements the
SkipUntil
operator to use lock-free methods and also fixes a potential race condition with the original setup when both observables signalOnError
concurrently.