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

Expose the mempack backend in git2 #593

Merged
merged 1 commit into from Jul 20, 2020
Merged

Conversation

staktrace
Copy link
Contributor

This also adds a method to override the ODB on the repository, which is also
exposed by libgit2. This allows the user to create a new ODB which e.g. just
has a mempack backend, and set it on the repository.

@staktrace
Copy link
Contributor Author

The part I'm uneasy about here is the c_int priority parameter that I'm exposing as an i32. I left a comment on libgit2/libgit2#5584 about it, but I'm not hopeful they'll change that API. Maybe we can wrap it in some sort of enum.

@staktrace staktrace force-pushed the mempack branch 2 times, most recently from 7ff7575 to 24dccb4 Compare July 17, 2020 23:44
Copy link
Member

@alexcrichton alexcrichton left a comment

Choose a reason for hiding this comment

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

Yeah seems fine to leave as i32 for now and defer to libgit2, but I'd otherwise like to just double check memory management to ensure these are indeed safe to call.

/// Override the object database for this repository
pub fn set_odb(&self, odb: &Odb<'_>) -> Result<(), Error> {
unsafe {
try_call!(raw::git_repository_set_odb(self.raw(), odb.raw()));
Copy link
Member

Choose a reason for hiding this comment

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

Can you double check the memory management here? Is it safe to drop Odb after this call?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So here, yes, it seems safe to drop Odb after this call. libgit2 internally does refcounting on the odb objects, and will only free the odb once it is not "owned" and the refcount drops to zero. Calling git_repository_set_odb will both mark the repo as the owner and increment the refcount, so if the rust code drops the ref it will continue to live until the repo itself gets destroyed or has a different odb installed.

self.raw,
mempack.raw(),
priority as c_int
));
Copy link
Member

Choose a reason for hiding this comment

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

Like below, can you check to see if it's safe to drop Mempack after this call?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This one is a bit weird. It looks like dropping the ref on the rust side is safe, because that won't actually free the C struct. In fact, the only thing that frees the C struct is the odb itself, here. So what could happen is if the rust code creates a mempack, doesn't attach it to an odb, and then drops it, it will get leaked. In that sense maybe it would be better to only allow the mempack to be created from an Odb object, and have it automatically added to that Odb so that even if the rust side drops the ref, it won't get leaked.

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 guess the other problem is that as-is, a rust user could create a mempack, add it to an odb, and then keep a ref to the mempack even after the odb is destroyed. That would be bad, as it would be a dangling pointer to freed memory.

I'll rework this so that the mempack can only be created from an odb and the lifetime is more tightly scoped.

This also adds a method to override the ODB on the repository, which is also
exposed by libgit2. This allows the user to create a new ODB, configure it,
and install it on the repository.
@staktrace
Copy link
Contributor Author

Ok, I updated the patch to do a better job with the lifetime management. I also added a test that exercises the new code, and a compile_fail doctest to ensure the lifetime is enforced.

@alexcrichton
Copy link
Member

Looks good to me, thanks!

@alexcrichton alexcrichton merged commit e36281d into rust-lang:master Jul 20, 2020
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.

None yet

2 participants