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