-
Notifications
You must be signed in to change notification settings - Fork 666
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
feat: mman NonNull
#2000
feat: mman NonNull
#2000
Conversation
9f5cfb7
to
b9be0e1
Compare
dfcc05d
to
099f78b
Compare
src/sys/mman.rs
Outdated
Ok(ret) | ||
} | ||
|
||
NonNull::new(ret).ok_or_else(Errno::last) |
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.
NonNull::new()
will ONLY return a None
if its argument is a null pointer, the error case of mmap
, whose return value libc::MAP_FAILED
((void *) -1 = 0xffffffff) is not null:
use std::ptr::NonNull;
fn main() {
let ptr = NonNull::new(libc::MAP_FAILED);
println!("{:?}", ptr);
}
$ cargo r -q
Some(0xffffffffffffffff)
which means that the current impl will return Ok(NonNull(0xffffffffff))
even when the underlying mmap()
failed
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've updated the implementation considering this.
Given that cc @asomers |
6b549e4
to
f2b0029
Compare
If it always returns a non-null pointer this seems even more reason to return |
f2b0029
to
5ce9eaa
Compare
5ce9eaa
to
454ccfd
Compare
I think both our points are correct here: From the interface safety perspetive, So I am not against this now, but still ping @asomers, I would like to hear your thoughts |
e15eae4
to
4a3bc01
Compare
Just adding my two cents here.
Additionally, this function is fallible and we are only one call away of turning the result into an The only reason why |
Makes sense to me, if we are gonna merge this change, should we also update the pub unsafe fn munmap(addr: NonNull<c_void>, len: size_t) -> Result<()> |
Yes, good point. For symmetry reasons, I believe all other functions in mman should implement this change, too. |
4a3bc01
to
a77786e
Compare
I've updated the PR with all the other changes. I think a follow-up PR could update the functions to take generic |
75abb35
to
a16937e
Compare
a16937e
to
a8942ce
Compare
9b3a981
to
b32fe4e
Compare
I agree, this is a way nicer abstraction, but since this function allocates in pages and doesn't care about the layout of The metadata of the slice pointer would then be the |
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 on the fence about this, because NonNull is less ergonomic than a plain pointer. But symmetry with Allocator is a good enough reason to do this, I think. I just noted one minor problem in some of the tests.
test/sys/test_mman.rs
Outdated
@@ -43,7 +47,7 @@ fn test_mremap_grow() { | |||
let slice: &mut [u8] = unsafe { | |||
#[cfg(target_os = "linux")] | |||
let mem = mremap( | |||
slice.as_mut_ptr().cast(), | |||
NonNull::from(&slice[..]).cast(), |
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.
Here you're mutating through an immutable pointer. That's not ok. You should do Slice::as_mut_ptr
or &mut slice
instead. It happens a few places below, too.
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.
Updated it to &mut slice[..]
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.
It seems that we can get rid of that #![allow(clippy::redundant_slicing)]
if we just use the slice
here, slice
itself is of type &mut [u8]
, the constructed NonNull
will be NonNull<[u8]>
, then we cast()
it to NonNull<c_void>
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 tried this, it fails in testing.
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.
Oops, sorry, &mut [u8]
is not Copy
, manually reborrowing here should do the trick
b32fe4e
to
2e5288a
Compare
} | ||
else { | ||
Ok(unsafe { NonNull::new_unchecked(ret) }) |
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.
Given that this is unsafe, do you think that we could add a comment stating it is safe, maybe something like:
mmap()
will never return a NULL pointer, it is safe to useNonNull::new_unchecked()
here
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.
Added comment.
@@ -468,7 +467,7 @@ pub unsafe fn mmap_anonymous( | |||
if ret == libc::MAP_FAILED { | |||
Err(Errno::last()) | |||
} else { | |||
Ok(ret) | |||
Ok(unsafe { NonNull::new_unchecked(ret) }) |
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.
Also this one
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.
Added comment.
new_size, | ||
flags.bits(), | ||
); | ||
|
||
if ret == libc::MAP_FAILED { | ||
Err(Errno::last()) | ||
} else { | ||
Ok(ret) | ||
Ok(unsafe { NonNull::new_unchecked(ret) }) |
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.
And this one: mremap()
will never return a NULL pointer, it is safe to use NonNull::new_unchecked()
here
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.
Added comment.
src/sys/mman.rs
Outdated
pub unsafe fn munmap(mut addr: NonNull<c_void>, len: size_t) -> Result<()> { | ||
Errno::result(libc::munmap(addr.as_mut(), len)).map(drop) |
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.
Why we are using NonNull.as_mut()
for munmap()
? Other functions are all using NonNull.as_ptr()
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.
Updated to NonNull::as_ptr
2e5288a
to
22eda8d
Compare
22eda8d
to
5756e07
Compare
Updates functions in
nix::sys::mman
to useNonNull
.The case where the returned pointer is null is the error case, therefore in the
Ok
case we can returnNonNull
.