Skip to content

Commit 7c41af2

Browse files
committed
Use the OS thread name by default for the current thread
1 parent 5c786a7 commit 7c41af2

File tree

6 files changed

+78
-3
lines changed

6 files changed

+78
-3
lines changed

library/std/src/sys/pal/unix/thread.rs

+39-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::cmp;
2-
use crate::ffi::CStr;
2+
use crate::ffi::{CStr, CString};
33
use crate::io;
44
use crate::mem;
55
use crate::num::NonZero;
@@ -225,6 +225,44 @@ impl Thread {
225225
// Newlib, Emscripten, and VxWorks have no way to set a thread name.
226226
}
227227

228+
#[cfg(target_os = "linux")]
229+
pub fn get_name() -> Option<CString> {
230+
const TASK_COMM_LEN: usize = 16;
231+
let mut name = vec![0u8; TASK_COMM_LEN];
232+
let res = unsafe {
233+
libc::pthread_getname_np(libc::pthread_self(), name.as_mut_ptr().cast(), name.len())
234+
};
235+
if res != 0 {
236+
return None;
237+
}
238+
name.truncate(name.iter().position(|&c| c == 0)?);
239+
CString::new(name).ok()
240+
}
241+
242+
#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))]
243+
pub fn get_name() -> Option<CString> {
244+
let mut name = vec![0u8; libc::MAXTHREADNAMESIZE];
245+
let res = unsafe {
246+
libc::pthread_getname_np(libc::pthread_self(), name.as_mut_ptr().cast(), name.len())
247+
};
248+
if res != 0 {
249+
return None;
250+
}
251+
name.truncate(name.iter().position(|&c| c == 0)?);
252+
CString::new(name).ok()
253+
}
254+
255+
#[cfg(not(any(
256+
target_os = "linux",
257+
target_os = "macos",
258+
target_os = "ios",
259+
target_os = "tvos",
260+
target_os = "watchos"
261+
)))]
262+
pub fn get_name() -> Option<CString> {
263+
None
264+
}
265+
228266
#[cfg(not(target_os = "espidf"))]
229267
pub fn sleep(dur: Duration) {
230268
let mut secs = dur.as_secs();

library/std/src/sys/pal/windows/c.rs

+6
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,12 @@ compat_fn_with_fallback! {
344344
SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); E_NOTIMPL
345345
}
346346

347+
// >= Win10 1607
348+
// https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getthreaddescription
349+
pub fn GetThreadDescription(hthread: HANDLE, lpthreaddescription: *mut PWSTR) -> HRESULT {
350+
SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); E_NOTIMPL
351+
}
352+
347353
// >= Win8 / Server 2012
348354
// https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemtimepreciseasfiletime
349355
pub fn GetSystemTimePreciseAsFileTime(lpsystemtimeasfiletime: *mut FILETIME) -> () {

library/std/src/sys/pal/windows/c/bindings.txt

+1
Original file line numberDiff line numberDiff line change
@@ -1923,6 +1923,7 @@ Windows.Win32.Foundation.HANDLE_FLAG_INHERIT
19231923
Windows.Win32.Foundation.HANDLE_FLAG_PROTECT_FROM_CLOSE
19241924
Windows.Win32.Foundation.HANDLE_FLAGS
19251925
Windows.Win32.Foundation.HMODULE
1926+
Windows.Win32.Foundation.LocalFree
19261927
Windows.Win32.Foundation.MAX_PATH
19271928
Windows.Win32.Foundation.NO_ERROR
19281929
Windows.Win32.Foundation.NTSTATUS

library/std/src/sys/pal/windows/c/windows_sys.rs

+5
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,10 @@ extern "system" {
379379
) -> BOOL;
380380
}
381381
#[link(name = "kernel32")]
382+
extern "system" {
383+
pub fn LocalFree(hmem: HLOCAL) -> HLOCAL;
384+
}
385+
#[link(name = "kernel32")]
382386
extern "system" {
383387
pub fn MoveFileExW(
384388
lpexistingfilename: PCWSTR,
@@ -3441,6 +3445,7 @@ pub type HANDLE_FLAGS = u32;
34413445
pub const HANDLE_FLAG_INHERIT: HANDLE_FLAGS = 1u32;
34423446
pub const HANDLE_FLAG_PROTECT_FROM_CLOSE: HANDLE_FLAGS = 2u32;
34433447
pub const HIGH_PRIORITY_CLASS: PROCESS_CREATION_FLAGS = 128u32;
3448+
pub type HLOCAL = *mut ::core::ffi::c_void;
34443449
pub type HMODULE = *mut ::core::ffi::c_void;
34453450
pub type HRESULT = i32;
34463451
pub const IDLE_PRIORITY_CLASS: PROCESS_CREATION_FLAGS = 64u32;

library/std/src/sys/pal/windows/thread.rs

+24-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use crate::sys::handle::Handle;
99
use crate::sys::stack_overflow;
1010
use crate::sys_common::FromInner;
1111
use crate::time::Duration;
12-
12+
use alloc::ffi::CString;
1313
use core::ffi::c_void;
1414

1515
use super::time::WaitableTimer;
@@ -71,6 +71,29 @@ impl Thread {
7171
};
7272
}
7373

74+
pub fn get_name() -> Option<CString> {
75+
unsafe {
76+
let mut ptr = core::ptr::null_mut();
77+
let result = c::GetThreadDescription(c::GetCurrentThread(), &mut ptr);
78+
if result < 0 {
79+
return None;
80+
}
81+
let name = String::from_utf16_lossy({
82+
let mut len = 0;
83+
while *ptr.add(len) != 0 {
84+
len += 1;
85+
}
86+
core::slice::from_raw_parts(ptr, len)
87+
})
88+
.into_bytes();
89+
// Attempt to free the memory.
90+
// This should never fail but if it does then there's not much we can do about it.
91+
let result = c::LocalFree(ptr.cast::<c_void>());
92+
debug_assert!(result.is_null());
93+
if name.is_empty() { None } else { Some(CString::from_vec_unchecked(name)) }
94+
}
95+
}
96+
7497
pub fn join(self) {
7598
let rc = unsafe { c::WaitForSingleObject(self.handle.as_raw_handle(), c::INFINITE) };
7699
if rc == c::WAIT_FAILED {

library/std/src/sys_common/thread_info.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#![allow(dead_code)] // stack_guard isn't used right now on all platforms
22

33
use crate::cell::OnceCell;
4+
use crate::sys;
45
use crate::sys::thread::guard::Guard;
56
use crate::thread::Thread;
67

@@ -23,7 +24,8 @@ impl ThreadInfo {
2324
{
2425
THREAD_INFO
2526
.try_with(move |thread_info| {
26-
let thread = thread_info.thread.get_or_init(|| Thread::new(None));
27+
let thread =
28+
thread_info.thread.get_or_init(|| Thread::new(sys::thread::Thread::get_name()));
2729
f(thread, &thread_info.stack_guard)
2830
})
2931
.ok()

0 commit comments

Comments
 (0)