about summary refs log tree commit diff
path: root/library/std/src/rt.rs
diff options
context:
space:
mode:
Diffstat (limited to 'library/std/src/rt.rs')
-rw-r--r--library/std/src/rt.rs21
1 files changed, 18 insertions, 3 deletions
diff --git a/library/std/src/rt.rs b/library/std/src/rt.rs
index 0a841f07e3b..80e7c3c026b 100644
--- a/library/std/src/rt.rs
+++ b/library/std/src/rt.rs
@@ -102,9 +102,24 @@ unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
         sys::init(argc, argv, sigpipe)
     };
 
-    // Set up the current thread to give it the right name.
-    let thread = Thread::new_main();
-    thread::set_current(thread);
+    // Set up the current thread handle to give it the right name.
+    //
+    // When code running before main uses `ReentrantLock` (for example by
+    // using `println!`), the thread ID can become initialized before we
+    // create this handle. Since `set_current` fails when the ID of the
+    // handle does not match the current ID, we should attempt to use the
+    // current thread ID here instead of unconditionally creating a new
+    // one. Also see #130210.
+    let thread = Thread::new_main(thread::current_id());
+    if let Err(_thread) = thread::set_current(thread) {
+        // `thread::current` will create a new handle if none has been set yet.
+        // Thus, if someone uses it before main, this call will fail. That's a
+        // bad idea though, as we then cannot set the main thread name here.
+        //
+        // FIXME: detect the main thread in `thread::current` and use the
+        //        correct name there.
+        rtabort!("code running before main must not use thread::current");
+    }
 }
 
 /// Clean up the thread-local runtime state. This *should* be run after all other