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

ImmutableDB.Iterator: allocate handles in the ResourceRegistry #1547

Merged
merged 3 commits into from
Jan 31, 2020

Conversation

mrBliss
Copy link
Contributor

@mrBliss mrBliss commented Jan 31, 2020

Fixes #1543.

The ChainDB.Iterators and ChainDB.Readers use ImmutableDB.Iterators internally. Both take a ResourceRegistry to allocate the ImmutableDB.Iterator in so that the ImmutableDB.Iterator and the open handle it contains is closed when an exception occurs.

If an exception occurs at the wrong time while opening an ImmutableDB.Iterator, after opening the handle, we might leak the handle. Fix this by directly allocating the handle in the ResourceRegistry instead of the ImmutableDB.Iterator that refers to the handle.

@mrBliss mrBliss added the consensus issues related to ouroboros-consensus label Jan 31, 2020
@mrBliss mrBliss requested review from edsko and nfrisby January 31, 2020 10:32
-- opened. For example, when closing the ImmutableDB/ChainDB from the
-- main thread, we'll close all open iterators, each of them opened in
-- a different thread.
unsafeRelease itEpochKey
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Comment is wrong (same for other unsafeRelease): the reason this was needed is because in the consensus tests, the protocol threads are spawned in a different ResourceRegistry than the ChainDB, see #1390. We're not going to fix that in this PR, but add a comment: "this is dangerous, because this allows the iterator to be used by a thread not spawned by this registry, so the iterator can disappear before the thread is terminated".

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Add a comment on #1390 about this.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm currently assuming that iteratorClose is sometimes called from a different thread than the one that created that registry. E.G. at a glance, it looks like ChainDB.Impl.implIteratorNext could be called from a spawned thread, and that calls ImmDB.iteratorClose.

So, even if iterators were managed by the ChainDB registry, wouldn't we see ResourceRegistryUsedFromUnknownThread without unsafeRelease? Or is my assumption wrong?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My comment (in the code) was wrong.

A resource can in fact be released from another thread, as long as that thread has been spawned by the same registry.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah ha! I was conflating the two error conditions in just the same way as the comment.

The name ResourceRegistryUsedFromUnknownThread is not wrong, but it does admit this misinterpretation. ResourceRegistryUsedFromUntrackedThread (or just the full ResourceRegistryUsedFromThreadNotInRegistry) would be clearer in this aspect, in hindsight.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The name ResourceRegistryUsedFromUnknownThread is not wrong, but it does admit this misinterpretation. ResourceRegistryUsedFromUntrackedThread (or just the full ResourceRegistryUsedFromThreadNotInRegistry) would be clearer in this aspect, in hindsight.

Agreed. Good idea!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have renamed ResourceRegistryUsedFromUnknownThread to ResourceRegistryUsedFromUntrackedThread (and updated the comments) in a separate commit.

Fixes #1543.

The ChainDB.Iterators and ChainDB.Readers use ImmutableDB.Iterators
internally. Both take a ResourceRegistry to allocate the ImmutableDB.Iterator
in so that the ImmutableDB.Iterator and the open handle it contains is closed
when an exception occurs.

If an exception occurs at the wrong time while opening an
ImmutableDB.Iterator, after opening the handle, we might leak the handle. Fix
this by directly allocating the handle in the ResourceRegistry instead of the
ImmutableDB.Iterator that refers to the handle.
See the updated docstring of the `ResourceRegistryUsedFromUnknownThread`
constructor.
@mrBliss
Copy link
Contributor Author

mrBliss commented Jan 31, 2020

bors r+

iohk-bors bot added a commit that referenced this pull request Jan 31, 2020
1547: ImmutableDB.Iterator: allocate handles in the ResourceRegistry r=mrBliss a=mrBliss

Fixes #1543.

The ChainDB.Iterators and ChainDB.Readers use ImmutableDB.Iterators internally. Both take a ResourceRegistry to allocate the ImmutableDB.Iterator in so that the ImmutableDB.Iterator and the open handle it contains is closed when an exception occurs.

If an exception occurs at the wrong time while opening an ImmutableDB.Iterator, after opening the handle, we might leak the handle. Fix this by directly allocating the handle in the ResourceRegistry instead of the ImmutableDB.Iterator that refers to the handle.

Co-authored-by: Thomas Winant <[email protected]>
@iohk-bors
Copy link
Contributor

iohk-bors bot commented Jan 31, 2020

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
consensus issues related to ouroboros-consensus
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ImmutableDB is leaking file handles
3 participants