|
1 | 1 | //@ignore-target-windows: No libc on Windows |
2 | 2 | #![feature(cstr_from_bytes_until_nul)] |
3 | | -use std::ffi::CStr; |
| 3 | +use std::ffi::{CStr, CString}; |
4 | 4 | use std::thread; |
5 | 5 |
|
6 | 6 | fn main() { |
@@ -135,18 +135,30 @@ fn test_named_thread_truncation() { |
135 | 135 | .chain(std::iter::repeat(" yada").take(100)) |
136 | 136 | .collect::<String>(); |
137 | 137 |
|
| 138 | + fn set_thread_name(name: &CStr) -> i32 { |
| 139 | + #[cfg(target_os = "linux")] |
| 140 | + return unsafe { libc::pthread_setname_np(libc::pthread_self(), name.as_ptr().cast()) }; |
| 141 | + #[cfg(target_os = "macos")] |
| 142 | + return unsafe { libc::pthread_setname_np(name.as_ptr().cast()) }; |
| 143 | + } |
| 144 | + |
138 | 145 | let result = thread::Builder::new().name(long_name.clone()).spawn(move || { |
139 | 146 | // Rust remembers the full thread name itself. |
140 | 147 | assert_eq!(thread::current().name(), Some(long_name.as_str())); |
141 | 148 |
|
142 | 149 | // But the system is limited -- make sure we successfully set a truncation. |
143 | 150 | let mut buf = vec![0u8; long_name.len() + 1]; |
144 | 151 | unsafe { |
145 | | - libc::pthread_getname_np(libc::pthread_self(), buf.as_mut_ptr().cast(), buf.len()); |
146 | | - } |
| 152 | + libc::pthread_getname_np(libc::pthread_self(), buf.as_mut_ptr().cast(), buf.len()) |
| 153 | + }; |
147 | 154 | let cstr = CStr::from_bytes_until_nul(&buf).unwrap(); |
148 | 155 | assert!(cstr.to_bytes().len() >= 15); // POSIX seems to promise at least 15 chars |
149 | 156 | assert!(long_name.as_bytes().starts_with(cstr.to_bytes())); |
| 157 | + |
| 158 | + // Also test directly calling pthread_setname to check its return value. |
| 159 | + assert_eq!(set_thread_name(&cstr), 0); |
| 160 | + // But with a too long name it should fail. |
| 161 | + assert_ne!(set_thread_name(&CString::new(long_name).unwrap()), 0); |
150 | 162 | }); |
151 | 163 | result.unwrap().join().unwrap(); |
152 | 164 | } |
0 commit comments