Skip to content

Commit 947d1fa

Browse files
authored
Rollup merge of rust-lang#136826 - xizheyin:issue-136737, r=thomcc
Replace mem::zeroed with mem::MaybeUninit::uninit for large struct in Unix As discussion in rust-lang#136737. - Replace `mem::zeroed()` with `MaybeUninit::uninit()` for `sockaddr_storage` in `accept()` and `recvfrom()` since these functions fill in the address structure - Replace `mem::zeroed()` with `MaybeUninit::uninit()` for `pthread_attr_t` in thread-related functions since `pthread_attr_init()` initializes the structure - Add references to man pages to document this behavior
2 parents 85335cc + 1893126 commit 947d1fa

File tree

4 files changed

+45
-26
lines changed

4 files changed

+45
-26
lines changed

Diff for: std/src/sys/net/connection/socket.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -557,10 +557,13 @@ impl TcpListener {
557557
}
558558

559559
pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
560-
let mut storage: c::sockaddr_storage = unsafe { mem::zeroed() };
560+
// The `accept` function will fill in the storage with the address,
561+
// so we don't need to zero it here.
562+
// reference: https://linux.die.net/man/2/accept4
563+
let mut storage: mem::MaybeUninit<c::sockaddr_storage> = mem::MaybeUninit::uninit();
561564
let mut len = mem::size_of_val(&storage) as c::socklen_t;
562-
let sock = self.inner.accept((&raw mut storage) as *mut _, &mut len)?;
563-
let addr = unsafe { socket_addr_from_c(&storage, len as usize)? };
565+
let sock = self.inner.accept(storage.as_mut_ptr() as *mut _, &mut len)?;
566+
let addr = unsafe { socket_addr_from_c(storage.as_ptr(), len as usize)? };
564567
Ok((TcpStream { inner: sock }, addr))
565568
}
566569

Diff for: std/src/sys/net/connection/socket/unix.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,10 @@ impl Socket {
322322
buf: &mut [u8],
323323
flags: c_int,
324324
) -> io::Result<(usize, SocketAddr)> {
325-
let mut storage: libc::sockaddr_storage = unsafe { mem::zeroed() };
325+
// The `recvfrom` function will fill in the storage with the address,
326+
// so we don't need to zero it here.
327+
// reference: https://linux.die.net/man/2/recvfrom
328+
let mut storage: mem::MaybeUninit<libc::sockaddr_storage> = mem::MaybeUninit::uninit();
326329
let mut addrlen = mem::size_of_val(&storage) as libc::socklen_t;
327330

328331
let n = cvt(unsafe {
@@ -335,7 +338,7 @@ impl Socket {
335338
&mut addrlen,
336339
)
337340
})?;
338-
Ok((n as usize, unsafe { socket_addr_from_c(&storage, addrlen as usize)? }))
341+
Ok((n as usize, unsafe { socket_addr_from_c(storage.as_ptr(), addrlen as usize)? }))
339342
}
340343

341344
pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {

Diff for: std/src/sys/pal/unix/stack_overflow.rs

+23-13
Original file line numberDiff line numberDiff line change
@@ -319,21 +319,27 @@ mod imp {
319319
))]
320320
unsafe fn get_stack_start() -> Option<*mut libc::c_void> {
321321
let mut ret = None;
322-
let mut attr: libc::pthread_attr_t = crate::mem::zeroed();
322+
let mut attr: mem::MaybeUninit<libc::pthread_attr_t> = mem::MaybeUninit::uninit();
323+
if !cfg!(target_os = "freebsd") {
324+
attr = mem::MaybeUninit::zeroed();
325+
}
323326
#[cfg(target_os = "freebsd")]
324-
assert_eq!(libc::pthread_attr_init(&mut attr), 0);
327+
assert_eq!(libc::pthread_attr_init(attr.as_mut_ptr()), 0);
325328
#[cfg(target_os = "freebsd")]
326-
let e = libc::pthread_attr_get_np(libc::pthread_self(), &mut attr);
329+
let e = libc::pthread_attr_get_np(libc::pthread_self(), attr.as_mut_ptr());
327330
#[cfg(not(target_os = "freebsd"))]
328-
let e = libc::pthread_getattr_np(libc::pthread_self(), &mut attr);
331+
let e = libc::pthread_getattr_np(libc::pthread_self(), attr.as_mut_ptr());
329332
if e == 0 {
330333
let mut stackaddr = crate::ptr::null_mut();
331334
let mut stacksize = 0;
332-
assert_eq!(libc::pthread_attr_getstack(&attr, &mut stackaddr, &mut stacksize), 0);
335+
assert_eq!(
336+
libc::pthread_attr_getstack(attr.as_ptr(), &mut stackaddr, &mut stacksize),
337+
0
338+
);
333339
ret = Some(stackaddr);
334340
}
335341
if e == 0 || cfg!(target_os = "freebsd") {
336-
assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
342+
assert_eq!(libc::pthread_attr_destroy(attr.as_mut_ptr()), 0);
337343
}
338344
ret
339345
}
@@ -509,16 +515,20 @@ mod imp {
509515
// FIXME: I am probably not unsafe.
510516
unsafe fn current_guard() -> Option<Range<usize>> {
511517
let mut ret = None;
512-
let mut attr: libc::pthread_attr_t = crate::mem::zeroed();
518+
519+
let mut attr: mem::MaybeUninit<libc::pthread_attr_t> = mem::MaybeUninit::uninit();
520+
if !cfg!(target_os = "freebsd") {
521+
attr = mem::MaybeUninit::zeroed();
522+
}
513523
#[cfg(target_os = "freebsd")]
514-
assert_eq!(libc::pthread_attr_init(&mut attr), 0);
524+
assert_eq!(libc::pthread_attr_init(attr.as_mut_ptr()), 0);
515525
#[cfg(target_os = "freebsd")]
516-
let e = libc::pthread_attr_get_np(libc::pthread_self(), &mut attr);
526+
let e = libc::pthread_attr_get_np(libc::pthread_self(), attr.as_mut_ptr());
517527
#[cfg(not(target_os = "freebsd"))]
518-
let e = libc::pthread_getattr_np(libc::pthread_self(), &mut attr);
528+
let e = libc::pthread_getattr_np(libc::pthread_self(), attr.as_mut_ptr());
519529
if e == 0 {
520530
let mut guardsize = 0;
521-
assert_eq!(libc::pthread_attr_getguardsize(&attr, &mut guardsize), 0);
531+
assert_eq!(libc::pthread_attr_getguardsize(attr.as_ptr(), &mut guardsize), 0);
522532
if guardsize == 0 {
523533
if cfg!(all(target_os = "linux", target_env = "musl")) {
524534
// musl versions before 1.1.19 always reported guard
@@ -531,7 +541,7 @@ mod imp {
531541
}
532542
let mut stackptr = crate::ptr::null_mut::<libc::c_void>();
533543
let mut size = 0;
534-
assert_eq!(libc::pthread_attr_getstack(&attr, &mut stackptr, &mut size), 0);
544+
assert_eq!(libc::pthread_attr_getstack(attr.as_ptr(), &mut stackptr, &mut size), 0);
535545

536546
let stackaddr = stackptr.addr();
537547
ret = if cfg!(any(target_os = "freebsd", target_os = "netbsd", target_os = "hurd")) {
@@ -552,7 +562,7 @@ mod imp {
552562
};
553563
}
554564
if e == 0 || cfg!(target_os = "freebsd") {
555-
assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
565+
assert_eq!(libc::pthread_attr_destroy(attr.as_mut_ptr()), 0);
556566
}
557567
ret
558568
}

Diff for: std/src/sys/pal/unix/thread.rs

+11-8
Original file line numberDiff line numberDiff line change
@@ -49,24 +49,27 @@ impl Thread {
4949
pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
5050
let p = Box::into_raw(Box::new(p));
5151
let mut native: libc::pthread_t = mem::zeroed();
52-
let mut attr: libc::pthread_attr_t = mem::zeroed();
53-
assert_eq!(libc::pthread_attr_init(&mut attr), 0);
52+
let mut attr: mem::MaybeUninit<libc::pthread_attr_t> = mem::MaybeUninit::uninit();
53+
assert_eq!(libc::pthread_attr_init(attr.as_mut_ptr()), 0);
5454

5555
#[cfg(target_os = "espidf")]
5656
if stack > 0 {
5757
// Only set the stack if a non-zero value is passed
5858
// 0 is used as an indication that the default stack size configured in the ESP-IDF menuconfig system should be used
5959
assert_eq!(
60-
libc::pthread_attr_setstacksize(&mut attr, cmp::max(stack, min_stack_size(&attr))),
60+
libc::pthread_attr_setstacksize(
61+
attr.as_mut_ptr(),
62+
cmp::max(stack, min_stack_size(&attr))
63+
),
6164
0
6265
);
6366
}
6467

6568
#[cfg(not(target_os = "espidf"))]
6669
{
67-
let stack_size = cmp::max(stack, min_stack_size(&attr));
70+
let stack_size = cmp::max(stack, min_stack_size(attr.as_ptr()));
6871

69-
match libc::pthread_attr_setstacksize(&mut attr, stack_size) {
72+
match libc::pthread_attr_setstacksize(attr.as_mut_ptr(), stack_size) {
7073
0 => {}
7174
n => {
7275
assert_eq!(n, libc::EINVAL);
@@ -77,16 +80,16 @@ impl Thread {
7780
let page_size = os::page_size();
7881
let stack_size =
7982
(stack_size + page_size - 1) & (-(page_size as isize - 1) as usize - 1);
80-
assert_eq!(libc::pthread_attr_setstacksize(&mut attr, stack_size), 0);
83+
assert_eq!(libc::pthread_attr_setstacksize(attr.as_mut_ptr(), stack_size), 0);
8184
}
8285
};
8386
}
8487

85-
let ret = libc::pthread_create(&mut native, &attr, thread_start, p as *mut _);
88+
let ret = libc::pthread_create(&mut native, attr.as_ptr(), thread_start, p as *mut _);
8689
// Note: if the thread creation fails and this assert fails, then p will
8790
// be leaked. However, an alternative design could cause double-free
8891
// which is clearly worse.
89-
assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
92+
assert_eq!(libc::pthread_attr_destroy(attr.as_mut_ptr()), 0);
9093

9194
return if ret != 0 {
9295
// The thread failed to start and as a result p was not consumed. Therefore, it is

0 commit comments

Comments
 (0)