158
158
#[cfg(all(test, not(any(target_os = "emscripten", target_os = "wasi"))))]
159
159
mod tests;
160
160
161
+ use core::cell::SyncUnsafeCell;
162
+ use core::ffi::CStr;
163
+ use core::mem::MaybeUninit;
164
+
161
165
use crate::any::Any;
162
166
use crate::cell::UnsafeCell;
163
- use crate::ffi::CStr;
164
167
use crate::marker::PhantomData;
165
168
use crate::mem::{self, ManuallyDrop, forget};
166
169
use crate::num::NonZero;
@@ -1125,7 +1128,7 @@ pub fn park_timeout(dur: Duration) {
1125
1128
let guard = PanicGuard;
1126
1129
// SAFETY: park_timeout is called on the parker owned by this thread.
1127
1130
unsafe {
1128
- current().inner.as_ref() .parker().park_timeout(dur);
1131
+ current().0 .parker().park_timeout(dur);
1129
1132
}
1130
1133
// No panic occurred, do not abort.
1131
1134
forget(guard);
@@ -1232,65 +1235,114 @@ impl ThreadId {
1232
1235
// Thread
1233
1236
////////////////////////////////////////////////////////////////////////////////
1234
1237
1235
- /// The internal representation of a `Thread`'s name.
1236
- enum ThreadName {
1237
- Main,
1238
- Other(ThreadNameString),
1239
- Unnamed,
1240
- }
1241
-
1242
1238
// This module ensures private fields are kept private, which is necessary to enforce the safety requirements.
1243
1239
mod thread_name_string {
1244
1240
use core::str;
1245
1241
1246
- use super::ThreadName;
1247
1242
use crate::ffi::{CStr, CString};
1248
1243
1249
1244
/// Like a `String` it's guaranteed UTF-8 and like a `CString` it's null terminated.
1250
1245
pub(crate) struct ThreadNameString {
1251
1246
inner: CString,
1252
1247
}
1248
+
1249
+ impl ThreadNameString {
1250
+ pub fn as_str(&self) -> &str {
1251
+ // SAFETY: `self.inner` is only initialised via `String`, which upholds the validity invariant of `str`.
1252
+ unsafe { str::from_utf8_unchecked(self.inner.to_bytes()) }
1253
+ }
1254
+ }
1255
+
1253
1256
impl core::ops::Deref for ThreadNameString {
1254
1257
type Target = CStr;
1255
1258
fn deref(&self) -> &CStr {
1256
1259
&self.inner
1257
1260
}
1258
1261
}
1262
+
1259
1263
impl From<String> for ThreadNameString {
1260
1264
fn from(s: String) -> Self {
1261
1265
Self {
1262
1266
inner: CString::new(s).expect("thread name may not contain interior null bytes"),
1263
1267
}
1264
1268
}
1265
1269
}
1266
- impl ThreadName {
1267
- pub fn as_cstr(&self) -> Option<&CStr> {
1268
- match self {
1269
- ThreadName::Main => Some(c"main"),
1270
- ThreadName::Other(other) => Some(other),
1271
- ThreadName::Unnamed => None,
1272
- }
1273
- }
1274
-
1275
- pub fn as_str(&self) -> Option<&str> {
1276
- // SAFETY: `as_cstr` can only return `Some` for a fixed CStr or a `ThreadNameString`,
1277
- // which is guaranteed to be UTF-8.
1278
- self.as_cstr().map(|s| unsafe { str::from_utf8_unchecked(s.to_bytes()) })
1279
- }
1280
- }
1281
1270
}
1282
1271
pub(crate) use thread_name_string::ThreadNameString;
1283
1272
1284
- /// The internal representation of a `Thread` handle
1285
- struct Inner {
1286
- name: ThreadName, // Guaranteed to be UTF-8
1273
+ static MAIN_THREAD_INFO: SyncUnsafeCell<(MaybeUninit<ThreadId>, MaybeUninit<Parker>)> =
1274
+ SyncUnsafeCell::new((MaybeUninit::uninit(), MaybeUninit::uninit()));
1275
+
1276
+ /// The internal representation of a `Thread` that is not the main thread.
1277
+ struct OtherInner {
1278
+ name: Option<ThreadNameString>,
1287
1279
id: ThreadId,
1288
1280
parker: Parker,
1289
1281
}
1290
1282
1283
+ /// The internal representation of a `Thread` handle.
1284
+ #[derive(Clone)]
1285
+ enum Inner {
1286
+ /// Represents the main thread. May only be constructed by Thread::new_main.
1287
+ Main(&'static (ThreadId, Parker)),
1288
+ /// Represents any other thread.
1289
+ Other(Pin<Arc<OtherInner>>),
1290
+ }
1291
+
1291
1292
impl Inner {
1292
- fn parker(self: Pin<&Self>) -> Pin<&Parker> {
1293
- unsafe { Pin::map_unchecked(self, |inner| &inner.parker) }
1293
+ fn id(&self) -> ThreadId {
1294
+ match self {
1295
+ Self::Main((thread_id, _)) => *thread_id,
1296
+ Self::Other(other) => other.id,
1297
+ }
1298
+ }
1299
+
1300
+ fn cname(&self) -> Option<&CStr> {
1301
+ match self {
1302
+ Self::Main(_) => Some(c"main"),
1303
+ Self::Other(other) => other.name.as_deref(),
1304
+ }
1305
+ }
1306
+
1307
+ fn name(&self) -> Option<&str> {
1308
+ match self {
1309
+ Self::Main(_) => Some("main"),
1310
+ Self::Other(other) => other.name.as_ref().map(ThreadNameString::as_str),
1311
+ }
1312
+ }
1313
+
1314
+ fn into_raw(self) -> *const () {
1315
+ match self {
1316
+ // Just return the pointer to `MAIN_THREAD_INFO`.
1317
+ Self::Main(ptr) => crate::ptr::from_ref(ptr).cast(),
1318
+ Self::Other(arc) => {
1319
+ // Safety: We only expose an opaque pointer, which maintains the `Pin` invariant.
1320
+ let inner = unsafe { Pin::into_inner_unchecked(arc) };
1321
+ Arc::into_raw(inner) as *const ()
1322
+ }
1323
+ }
1324
+ }
1325
+
1326
+ /// # Safety
1327
+ ///
1328
+ /// See [`Thread::from_raw`].
1329
+ unsafe fn from_raw(ptr: *const ()) -> Self {
1330
+ // If the pointer is to `MAIN_THREAD_INFO`, we know it is the `Main` variant.
1331
+ if crate::ptr::eq(ptr.cast(), &MAIN_THREAD_INFO) {
1332
+ Self::Main(unsafe { &*ptr.cast() })
1333
+ } else {
1334
+ // Safety: Upheld by caller
1335
+ Self::Other(unsafe { Pin::new_unchecked(Arc::from_raw(ptr as *const OtherInner)) })
1336
+ }
1337
+ }
1338
+
1339
+ fn parker(&self) -> Pin<&Parker> {
1340
+ match self {
1341
+ Self::Main((_, parker_ref)) => Pin::static_ref(parker_ref),
1342
+ Self::Other(inner) => unsafe {
1343
+ Pin::map_unchecked(inner.as_ref(), |inner| &inner.parker)
1344
+ },
1345
+ }
1294
1346
}
1295
1347
}
1296
1348
@@ -1314,41 +1366,55 @@ impl Inner {
1314
1366
/// docs of [`Builder`] and [`spawn`] for more details.
1315
1367
///
1316
1368
/// [`thread::current`]: current::current
1317
- pub struct Thread {
1318
- inner: Pin<Arc<Inner>>,
1319
- }
1369
+ pub struct Thread(Inner);
1320
1370
1321
1371
impl Thread {
1322
1372
/// Used only internally to construct a thread object without spawning.
1323
1373
pub(crate) fn new(id: ThreadId, name: String) -> Thread {
1324
- Self::new_inner(id, ThreadName::Other (name.into( )))
1374
+ Self::new_inner(id, Some(ThreadNameString::from (name)))
1325
1375
}
1326
1376
1327
1377
pub(crate) fn new_unnamed(id: ThreadId) -> Thread {
1328
- Self::new_inner(id, ThreadName::Unnamed )
1378
+ Self::new_inner(id, None )
1329
1379
}
1330
1380
1331
- /// Constructs the thread handle for the main thread.
1332
- pub(crate) fn new_main(id: ThreadId) -> Thread {
1333
- Self::new_inner(id, ThreadName::Main)
1381
+ /// Used in runtime to construct main thread
1382
+ ///
1383
+ /// # Safety
1384
+ ///
1385
+ /// This must only ever be called once, and must be called on the main thread.
1386
+ pub(crate) unsafe fn new_main(thread_id: ThreadId) -> Thread {
1387
+ // Safety: As this is only called once and on the main thread, nothing else is accessing MAIN_THREAD_INFO
1388
+ // as the only other read occurs in `main_thread_info` *after* the main thread has been constructed,
1389
+ // and this function is the only one that constructs the main thread.
1390
+ //
1391
+ // Pre-main thread spawning cannot hit this either, as the caller promises that this is only called on the main thread.
1392
+ let main_thread_info = unsafe { &mut *MAIN_THREAD_INFO.get() };
1393
+
1394
+ unsafe { Parker::new_in_place((&raw mut main_thread_info.1).cast()) };
1395
+ main_thread_info.0.write(thread_id);
1396
+
1397
+ // Store a `'static` ref to the initialised ThreadId and Parker,
1398
+ // to avoid having to repeatedly prove initialisation.
1399
+ Self(Inner::Main(unsafe { &*MAIN_THREAD_INFO.get().cast() }))
1334
1400
}
1335
1401
1336
- fn new_inner(id: ThreadId, name: ThreadName ) -> Thread {
1402
+ fn new_inner(id: ThreadId, name: Option<ThreadNameString> ) -> Thread {
1337
1403
// We have to use `unsafe` here to construct the `Parker` in-place,
1338
1404
// which is required for the UNIX implementation.
1339
1405
//
1340
1406
// SAFETY: We pin the Arc immediately after creation, so its address never
1341
1407
// changes.
1342
1408
let inner = unsafe {
1343
- let mut arc = Arc::<Inner >::new_uninit();
1409
+ let mut arc = Arc::<OtherInner >::new_uninit();
1344
1410
let ptr = Arc::get_mut_unchecked(&mut arc).as_mut_ptr();
1345
1411
(&raw mut (*ptr).name).write(name);
1346
1412
(&raw mut (*ptr).id).write(id);
1347
1413
Parker::new_in_place(&raw mut (*ptr).parker);
1348
1414
Pin::new_unchecked(arc.assume_init())
1349
1415
};
1350
1416
1351
- Thread { inner }
1417
+ Self(Inner::Other( inner))
1352
1418
}
1353
1419
1354
1420
/// Like the public [`park`], but callable on any handle. This is used to
@@ -1357,7 +1423,7 @@ impl Thread {
1357
1423
/// # Safety
1358
1424
/// May only be called from the thread to which this handle belongs.
1359
1425
pub(crate) unsafe fn park(&self) {
1360
- unsafe { self.inner.as_ref() .parker().park() }
1426
+ unsafe { self.0 .parker().park() }
1361
1427
}
1362
1428
1363
1429
/// Atomically makes the handle's token available if it is not already.
@@ -1393,7 +1459,7 @@ impl Thread {
1393
1459
#[stable(feature = "rust1", since = "1.0.0")]
1394
1460
#[inline]
1395
1461
pub fn unpark(&self) {
1396
- self.inner.as_ref() .parker().unpark();
1462
+ self.0 .parker().unpark();
1397
1463
}
1398
1464
1399
1465
/// Gets the thread's unique identifier.
@@ -1413,7 +1479,7 @@ impl Thread {
1413
1479
#[stable(feature = "thread_id", since = "1.19.0")]
1414
1480
#[must_use]
1415
1481
pub fn id(&self) -> ThreadId {
1416
- self.inner .id
1482
+ self.0 .id()
1417
1483
}
1418
1484
1419
1485
/// Gets the thread's name.
@@ -1456,7 +1522,11 @@ impl Thread {
1456
1522
#[stable(feature = "rust1", since = "1.0.0")]
1457
1523
#[must_use]
1458
1524
pub fn name(&self) -> Option<&str> {
1459
- self.inner.name.as_str()
1525
+ self.0.name()
1526
+ }
1527
+
1528
+ fn cname(&self) -> Option<&CStr> {
1529
+ self.0.cname()
1460
1530
}
1461
1531
1462
1532
/// Consumes the `Thread`, returning a raw pointer.
@@ -1480,9 +1550,7 @@ impl Thread {
1480
1550
/// ```
1481
1551
#[unstable(feature = "thread_raw", issue = "97523")]
1482
1552
pub fn into_raw(self) -> *const () {
1483
- // Safety: We only expose an opaque pointer, which maintains the `Pin` invariant.
1484
- let inner = unsafe { Pin::into_inner_unchecked(self.inner) };
1485
- Arc::into_raw(inner) as *const ()
1553
+ self.0.into_raw()
1486
1554
}
1487
1555
1488
1556
/// Constructs a `Thread` from a raw pointer.
@@ -1504,11 +1572,7 @@ impl Thread {
1504
1572
#[unstable(feature = "thread_raw", issue = "97523")]
1505
1573
pub unsafe fn from_raw(ptr: *const ()) -> Thread {
1506
1574
// Safety: Upheld by caller.
1507
- unsafe { Thread { inner: Pin::new_unchecked(Arc::from_raw(ptr as *const Inner)) } }
1508
- }
1509
-
1510
- fn cname(&self) -> Option<&CStr> {
1511
- self.inner.name.as_cstr()
1575
+ unsafe { Thread(Inner::from_raw(ptr)) }
1512
1576
}
1513
1577
}
1514
1578
0 commit comments