Safely enforce thread name requirements
This commit is contained in:
@@ -161,7 +161,7 @@ mod tests;
|
|||||||
use crate::any::Any;
|
use crate::any::Any;
|
||||||
use crate::cell::{OnceCell, UnsafeCell};
|
use crate::cell::{OnceCell, UnsafeCell};
|
||||||
use crate::env;
|
use crate::env;
|
||||||
use crate::ffi::{CStr, CString};
|
use crate::ffi::CStr;
|
||||||
use crate::fmt;
|
use crate::fmt;
|
||||||
use crate::io;
|
use crate::io;
|
||||||
use crate::marker::PhantomData;
|
use crate::marker::PhantomData;
|
||||||
@@ -487,11 +487,7 @@ impl Builder {
|
|||||||
amt
|
amt
|
||||||
});
|
});
|
||||||
|
|
||||||
let my_thread = name.map_or_else(Thread::new_unnamed, |name| unsafe {
|
let my_thread = name.map_or_else(Thread::new_unnamed, |name| Thread::new(name.into()));
|
||||||
Thread::new(
|
|
||||||
CString::new(name).expect("thread name may not contain interior null bytes"),
|
|
||||||
)
|
|
||||||
});
|
|
||||||
let their_thread = my_thread.clone();
|
let their_thread = my_thread.clone();
|
||||||
|
|
||||||
let my_packet: Arc<Packet<'scope, T>> = Arc::new(Packet {
|
let my_packet: Arc<Packet<'scope, T>> = Arc::new(Packet {
|
||||||
@@ -1273,10 +1269,34 @@ impl ThreadId {
|
|||||||
/// The internal representation of a `Thread`'s name.
|
/// The internal representation of a `Thread`'s name.
|
||||||
enum ThreadName {
|
enum ThreadName {
|
||||||
Main,
|
Main,
|
||||||
Other(CString),
|
Other(ThreadNameString),
|
||||||
Unnamed,
|
Unnamed,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This module ensures private fields are kept private, which is necessary to enforce the safety requirements.
|
||||||
|
mod thread_name_string {
|
||||||
|
use crate::ffi::{CStr, CString};
|
||||||
|
|
||||||
|
/// Like a `String` it's guaranteed UTF-8 and like a `CString` it's null terminated.
|
||||||
|
pub(crate) struct ThreadNameString {
|
||||||
|
inner: CString,
|
||||||
|
}
|
||||||
|
impl core::ops::Deref for ThreadNameString {
|
||||||
|
type Target = CStr;
|
||||||
|
fn deref(&self) -> &CStr {
|
||||||
|
&self.inner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl From<String> for ThreadNameString {
|
||||||
|
fn from(s: String) -> Self {
|
||||||
|
Self {
|
||||||
|
inner: CString::new(s).expect("thread name may not contain interior null bytes"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub(crate) use thread_name_string::ThreadNameString;
|
||||||
|
|
||||||
/// The internal representation of a `Thread` handle
|
/// The internal representation of a `Thread` handle
|
||||||
struct Inner {
|
struct Inner {
|
||||||
name: ThreadName, // Guaranteed to be UTF-8
|
name: ThreadName, // Guaranteed to be UTF-8
|
||||||
@@ -1316,10 +1336,7 @@ pub struct Thread {
|
|||||||
|
|
||||||
impl Thread {
|
impl Thread {
|
||||||
/// Used only internally to construct a thread object without spawning.
|
/// Used only internally to construct a thread object without spawning.
|
||||||
///
|
pub(crate) fn new(name: ThreadNameString) -> Thread {
|
||||||
/// # Safety
|
|
||||||
/// `name` must be valid UTF-8.
|
|
||||||
pub(crate) unsafe fn new(name: CString) -> Thread {
|
|
||||||
unsafe { Self::new_inner(ThreadName::Other(name)) }
|
unsafe { Self::new_inner(ThreadName::Other(name)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user