mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-09-08 00:00:13 +02:00
Replace (some) uninitialized with MaybeUninit (#1295)
This commit is contained in:
committed by
Sean McArthur
parent
0d99ddd4f4
commit
6d186fe40e
+55
-25
@@ -5,7 +5,7 @@ use crate::loom::{sync::atomic::AtomicUsize, sync::CausalCell};
|
|||||||
use futures_core::ready;
|
use futures_core::ready;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::mem::{self, ManuallyDrop};
|
use std::mem::MaybeUninit;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::sync::atomic::Ordering::{self, AcqRel, Acquire};
|
use std::sync::atomic::Ordering::{self, AcqRel, Acquire};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@@ -73,10 +73,10 @@ struct Inner<T> {
|
|||||||
value: CausalCell<Option<T>>,
|
value: CausalCell<Option<T>>,
|
||||||
|
|
||||||
/// The task to notify when the receiver drops without consuming the value.
|
/// The task to notify when the receiver drops without consuming the value.
|
||||||
tx_task: CausalCell<ManuallyDrop<Waker>>,
|
tx_task: CausalCell<MaybeUninit<Waker>>,
|
||||||
|
|
||||||
/// The task to notify when the value is sent.
|
/// The task to notify when the value is sent.
|
||||||
rx_task: CausalCell<ManuallyDrop<Waker>>,
|
rx_task: CausalCell<MaybeUninit<Waker>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
@@ -117,8 +117,8 @@ pub fn channel<T>() -> (Sender<T>, Receiver<T>) {
|
|||||||
let inner = Arc::new(Inner {
|
let inner = Arc::new(Inner {
|
||||||
state: AtomicUsize::new(State::new().as_usize()),
|
state: AtomicUsize::new(State::new().as_usize()),
|
||||||
value: CausalCell::new(None),
|
value: CausalCell::new(None),
|
||||||
tx_task: CausalCell::new(ManuallyDrop::new(unsafe { mem::uninitialized() })),
|
tx_task: CausalCell::new(MaybeUninit::uninit()),
|
||||||
rx_task: CausalCell::new(ManuallyDrop::new(unsafe { mem::uninitialized() })),
|
rx_task: CausalCell::new(MaybeUninit::uninit()),
|
||||||
});
|
});
|
||||||
|
|
||||||
let tx = Sender {
|
let tx = Sender {
|
||||||
@@ -177,9 +177,7 @@ impl<T> Sender<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if state.is_tx_task_set() {
|
if state.is_tx_task_set() {
|
||||||
let will_notify = inner
|
let will_notify = unsafe { inner.with_tx_task(|w| w.will_wake(cx.waker())) };
|
||||||
.tx_task
|
|
||||||
.with(|ptr| unsafe { (&*ptr).will_wake(cx.waker()) });
|
|
||||||
|
|
||||||
if !will_notify {
|
if !will_notify {
|
||||||
state = State::unset_tx_task(&inner.state);
|
state = State::unset_tx_task(&inner.state);
|
||||||
@@ -333,7 +331,9 @@ impl<T> Inner<T> {
|
|||||||
|
|
||||||
if prev.is_rx_task_set() {
|
if prev.is_rx_task_set() {
|
||||||
// TODO: Consume waker?
|
// TODO: Consume waker?
|
||||||
self.rx_task.with(|ptr| unsafe { (&*ptr).wake_by_ref() });
|
unsafe {
|
||||||
|
self.with_rx_task(Waker::wake_by_ref);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
true
|
true
|
||||||
@@ -352,9 +352,7 @@ impl<T> Inner<T> {
|
|||||||
Ready(Err(RecvError(())))
|
Ready(Err(RecvError(())))
|
||||||
} else {
|
} else {
|
||||||
if state.is_rx_task_set() {
|
if state.is_rx_task_set() {
|
||||||
let will_notify = self
|
let will_notify = unsafe { self.with_rx_task(|w| w.will_wake(cx.waker())) };
|
||||||
.rx_task
|
|
||||||
.with(|ptr| unsafe { (&*ptr).will_wake(cx.waker()) });
|
|
||||||
|
|
||||||
// Check if the task is still the same
|
// Check if the task is still the same
|
||||||
if !will_notify {
|
if !will_notify {
|
||||||
@@ -399,7 +397,9 @@ impl<T> Inner<T> {
|
|||||||
let prev = State::set_closed(&self.state);
|
let prev = State::set_closed(&self.state);
|
||||||
|
|
||||||
if prev.is_tx_task_set() && !prev.is_complete() {
|
if prev.is_tx_task_set() && !prev.is_complete() {
|
||||||
self.tx_task.with(|ptr| unsafe { (&*ptr).wake_by_ref() });
|
unsafe {
|
||||||
|
self.with_tx_task(Waker::wake_by_ref);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -408,22 +408,52 @@ impl<T> Inner<T> {
|
|||||||
self.value.with_mut(|ptr| (*ptr).take())
|
self.value.with_mut(|ptr| (*ptr).take())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe fn with_rx_task<F, R>(&self, f: F) -> R
|
||||||
|
where
|
||||||
|
F: FnOnce(&Waker) -> R,
|
||||||
|
{
|
||||||
|
self.rx_task.with(|ptr| {
|
||||||
|
let waker: *const Waker = (&*ptr).as_ptr();
|
||||||
|
f(&*waker)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn with_tx_task<F, R>(&self, f: F) -> R
|
||||||
|
where
|
||||||
|
F: FnOnce(&Waker) -> R,
|
||||||
|
{
|
||||||
|
self.tx_task.with(|ptr| {
|
||||||
|
let waker: *const Waker = (&*ptr).as_ptr();
|
||||||
|
f(&*waker)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
unsafe fn drop_rx_task(&self) {
|
unsafe fn drop_rx_task(&self) {
|
||||||
self.rx_task.with_mut(|ptr| ManuallyDrop::drop(&mut *ptr))
|
self.rx_task.with_mut(|ptr| {
|
||||||
|
let ptr: *mut Waker = (&mut *ptr).as_mut_ptr();
|
||||||
|
ptr.drop_in_place();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn drop_tx_task(&self) {
|
unsafe fn drop_tx_task(&self) {
|
||||||
self.tx_task.with_mut(|ptr| ManuallyDrop::drop(&mut *ptr))
|
self.tx_task.with_mut(|ptr| {
|
||||||
|
let ptr: *mut Waker = (&mut *ptr).as_mut_ptr();
|
||||||
|
ptr.drop_in_place();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn set_rx_task(&self, cx: &mut Context<'_>) {
|
unsafe fn set_rx_task(&self, cx: &mut Context<'_>) {
|
||||||
self.rx_task
|
self.rx_task.with_mut(|ptr| {
|
||||||
.with_mut(|ptr| *ptr = ManuallyDrop::new(cx.waker().clone()));
|
let ptr: *mut Waker = (&mut *ptr).as_mut_ptr();
|
||||||
|
ptr.write(cx.waker().clone());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn set_tx_task(&self, cx: &mut Context<'_>) {
|
unsafe fn set_tx_task(&self, cx: &mut Context<'_>) {
|
||||||
self.tx_task
|
self.tx_task.with_mut(|ptr| {
|
||||||
.with_mut(|ptr| *ptr = ManuallyDrop::new(cx.waker().clone()));
|
let ptr: *mut Waker = (&mut *ptr).as_mut_ptr();
|
||||||
|
ptr.write(cx.waker().clone());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -435,15 +465,15 @@ impl<T> Drop for Inner<T> {
|
|||||||
let state = State(*self.state.get_mut());
|
let state = State(*self.state.get_mut());
|
||||||
|
|
||||||
if state.is_rx_task_set() {
|
if state.is_rx_task_set() {
|
||||||
self.rx_task.with_mut(|ptr| unsafe {
|
unsafe {
|
||||||
ManuallyDrop::drop(&mut *ptr);
|
self.drop_rx_task();
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if state.is_tx_task_set() {
|
if state.is_tx_task_set() {
|
||||||
self.tx_task.with_mut(|ptr| unsafe {
|
unsafe {
|
||||||
ManuallyDrop::drop(&mut *ptr);
|
self.drop_tx_task();
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,20 +83,24 @@ pub mod impl_linux {
|
|||||||
pub mod impl_macos {
|
pub mod impl_macos {
|
||||||
use crate::UnixStream;
|
use crate::UnixStream;
|
||||||
use libc::getpeereid;
|
use libc::getpeereid;
|
||||||
|
use std::io;
|
||||||
|
use std::mem::MaybeUninit;
|
||||||
use std::os::unix::io::AsRawFd;
|
use std::os::unix::io::AsRawFd;
|
||||||
use std::{io, mem};
|
|
||||||
|
|
||||||
pub fn get_peer_cred(sock: &UnixStream) -> io::Result<super::UCred> {
|
pub fn get_peer_cred(sock: &UnixStream) -> io::Result<super::UCred> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let raw_fd = sock.as_raw_fd();
|
let raw_fd = sock.as_raw_fd();
|
||||||
|
|
||||||
#[allow(deprecated)]
|
let mut uid = MaybeUninit::uninit();
|
||||||
let mut cred: super::UCred = mem::uninitialized();
|
let mut gid = MaybeUninit::uninit();
|
||||||
|
|
||||||
let ret = getpeereid(raw_fd, &mut cred.uid, &mut cred.gid);
|
let ret = getpeereid(raw_fd, uid.as_mut_ptr(), gid.as_mut_ptr());
|
||||||
|
|
||||||
if ret == 0 {
|
if ret == 0 {
|
||||||
Ok(cred)
|
Ok(super::UCred {
|
||||||
|
uid: uid.assume_init(),
|
||||||
|
gid: gid.assume_init(),
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
Err(io::Error::last_os_error())
|
Err(io::Error::last_os_error())
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user