Skip to content
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

Make the list of segments more abstract #1563

Merged
merged 5 commits into from
Apr 10, 2020
Merged

Make the list of segments more abstract #1563

merged 5 commits into from
Apr 10, 2020

Conversation

ndkoval
Copy link
Member

@ndkoval ndkoval commented Sep 22, 2019

Make the list of segments more abstract, so that it can be used for stacks and channels

@ndkoval ndkoval force-pushed the segment-list branch 2 times, most recently from bcde8c4 to 6619690 Compare September 27, 2019 00:50
@ndkoval ndkoval changed the title [DO NOT MERGE] Make the list of segments more abstract Make the list of segments more abstract Sep 27, 2019
Copy link
Collaborator

@dkhalanskyjb dkhalanskyjb left a comment

Choose a reason for hiding this comment

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

There are some slightly troubling findings. They don't affect the semaphore implementation, but maybe they can still be considered bugs, in which case they shouldn't be hard to fix. Otherwise, the requirements for calling these methods should probably be stated clearly in the documentation.

assert { removed } // The segment should be logically removed at first
// Read `next` and `prev` pointers.
var next = this.nextOrClosed.segment ?: return // tail cannot be removed
var prev = prev.value ?: return // head cannot be removed
Copy link
Collaborator

Choose a reason for hiding this comment

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

It seems that there is no problem here, even though there used to be one and the fix isn't incorporated here.

Suggestions

Does the check for the prev.value do anything useful? Nothing bad happens if the null in prev is propagated to the right in the removed segments. Even if there are reasons to leave this check, the comment is misleading: if we believe that the head is the segment to which head points, assert { removed } ensures that this method could not have been called on a head; if, instead, we believe that the head is the rightmost segment with prev == null, then it isn't clear why it can't be removed.

Background

A quick explanation of what was the problem and why it doesn't matter any longer.

The problem that used to be present in this place is that the previous version of the remove() method had a (negligible) probability of a memory leak here, because it was possible that the segment after the one to which the head points could still have prev point to a segment to the left of head (for example, 3.prev could point to segment 1 even though head would point to 2 and 1 shouldn't have been accessible). Arbitrarily long links could be formed this way.

In this version, the problem is absent because head may only ever point to a non-removed segment, ensuring that segment removal can't propagate through the segments which are pointed to.

@ndkoval
Copy link
Member Author

ndkoval commented Dec 9, 2019

I have updated the data structure in a way so that it can be used for an efficient list of cancellable JobNodes implementation.

@ndkoval ndkoval removed the request for review from SokolovaMaria December 9, 2019 23:37
Copy link
Collaborator

@dkhalanskyjb dkhalanskyjb left a comment

Choose a reason for hiding this comment

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

I didn't look at the tests, and the implementation itself looks fine. The most notable change is a major overhaul of remove , which doesn't break the invariants necessary for everything to be correct. The potentially dangerous bugs that were found earlier are properly fixed.

@ndkoval ndkoval force-pushed the segment-list branch 3 times, most recently from 9f5f0c1 to a0106a8 Compare December 26, 2019 21:54
@elizarov elizarov force-pushed the segment-list branch 2 times, most recently from a62d1a4 to bc1adf2 Compare February 14, 2020 12:55
@qwwdfsad qwwdfsad force-pushed the develop branch 3 times, most recently from 4a49830 to aff8202 Compare March 10, 2020 17:27
…ther synchronization and communication primitives
@elizarov elizarov merged commit d75d02a into develop Apr 10, 2020
@elizarov elizarov deleted the segment-list branch April 10, 2020 17:11
qwwdfsad pushed a commit that referenced this pull request Apr 24, 2020
* Make the list of segments more abstract, so that it can be used for other synchronization and communication primitives

Co-authored-by: Roman Elizarov <[email protected]>
recheej pushed a commit to recheej/kotlinx.coroutines that referenced this pull request Dec 28, 2020
* Make the list of segments more abstract, so that it can be used for other synchronization and communication primitives

Co-authored-by: Roman Elizarov <[email protected]>
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.

3 participants