-
Notifications
You must be signed in to change notification settings - Fork 48
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
Impl drop for HandleData #94
Conversation
This is safer than assuming a function will be called. Also fixes some unnecessary mutability warnings
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.
This seems like an improvement! Is there a reason it's only a draft?
@@ -311,7 +318,7 @@ fn _network_read_range( | |||
// - 1 is used because the HTTP convention is to use inclusive start and end offsets | |||
let end = offset as usize + size_to_read - 1; | |||
let hvalue = format!("bytes={}-{}", offset, end); | |||
let mut hd = unsafe { &mut *(handle as *const c_void as *mut HandleData) }; | |||
let hd = unsafe { &mut *(handle as *const c_void as *mut HandleData) }; |
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.
The current logic is so simple it's probably not worth changing but I wanted to make sure you were aware of @pka's https://github.com/pka/http-range-client - which was pulled out of some of our work on the flatgeobuf client
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.
I was not aware! This looks very interesting…
I'm still trying to figure out whether there's anything Drop-related I've failed to take account of when returning early / bubbling an error (this is a potential problem with the existing code too) |
933f331
to
f3d765a
Compare
Hmmm. I've just checked (added a print statement to the |
Sooo I think we have been leaking a little bit of memory for…a while It turns out that On the way out: With this PR, on the way in ( And this triggers the new manual |
You can also apparently
but everything I've read says you should really avoid |
Option<*const c_char> isn't FFI-safe as it's doubly-nullable, and isn't handled under Option's current guaranteed special cases. Using Option<NonNull<c_char>> is allowed, however.
More investigation reveals that |
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 for the slow review. It's very much outside of what I'm familiar with.
I did spend some time reading about opaque pointers and boxing/ownership stuff and this all seems correct.
I also built and verified that the drop implementation is at least getting called sometimes.
So I guess: looks good to me in as as far as I'm good at looking.
And thanks for the explanations — I learned some things.
I was in the same situation til I started asking, and only found out that there are special FFI rules and exceptions for I'm having a last niggling uncertainty about passing around RequestBuilder (HeaderMap is OK), because it can't be verified with Miri – even though we use the Blocking version, it's still Tokio under the hood, which currently prevents analysis. I'm going to just ask on URLO tomorrow, and merge if the consensus is that it's safe. Thanks for looking at it! |
The RequestBuilder struct is complex and uses Tokio under the hood. Instead of passing it around, we pass the URL around and create a new Client for data retrieval. This is a bit less efficient since we don't use the connection pool created by the initial Client, but it's also safer.
bors try |
tryBuild succeeded: |
bors r+ |
Build succeeded: |
I see that you ended up removcing the opaque pointer and are rebuilding the request builder from a url. I would have guessed it was safe. Did you learn something that made this seem necessary, or was it more-so an abundance of caution in the face of uncertainty? To be clear, I'm fine with the change! Just hoping to learn more. |
It potentially contains I'm somewhat torn, but the resource-creation overhead is dwarfed by the data retrieval time. |
So to make sure I'm following your rationale:
That seems too scary to be true! Wouldn't that preclude sending almost any pointer to C? And how could anyone expect to do that analysis? My understanding is that whether a type is FFI-safe refers only to the type in the API - in this case the pointer. Since pointers are FFI safe, end of story. The internal structure of whatever is being pointed to is completely opaque and untouched by C. So specifically, the concern about Options might be relevant if the api was something like:
And indeed if you try to compile that, you'll see:
But if we only pass a pointer, since pointers are FFI safe, that should be fine:
And indeed this produces no FFI warning. I could be way off though. I'm still just figuring this out though... |
And to reiterate, I'm not worried at all about the perf repercussions of your change. I think it's totally fine. I'm just trying to get better at rust FFI stuff. Thanks for talking it through with me! |
This a draft PR to investigate the possibility of improving the safety of the
network
functionality.ATM, this is just a move of the pointer-reconstitution logic into a
Drop
impl (This is safer than assuming a function will be called, although of coursedrop()
isn't called on panic), but there will hopefully be more to come when I've done some more digging.This also fixes some unnecessary mutability and borrows, and makes the struct we pass to libproj
repr c
.