Repository navigation
fix: support glibc < 2.30 #6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
622a55d
fix: support glibc < 2.30
markovejnovic b76d2cb
chore: some cleanup
markovejnovic a091d18
ci: test on rockylinux:8 so glibc < 2.30 keeps linking
markovejnovic 9adbbf0
Merge remote-tracking branch 'origin/main' into atuin/fix/compile-on-…
markovejnovic File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| //! Apple-specific OS utilities. | ||
| #![allow(unsafe_code, reason = "need to call system utilities in os code")] | ||
|
|
||
| /// Get the current system thread id. | ||
| #[inline] | ||
| pub(super) fn gettid() -> u64 { | ||
| let mut id: u64 = 0; | ||
| // SAFETY: id is stack-allocated and guaranteed to outlast the call. | ||
| let res = unsafe { libc::pthread_threadid_np(0, &mut id) }; | ||
|
|
||
| (res == 0) | ||
| .then_some(id) | ||
| .expect("pthread_threadid_np only fails for NULL id or dead thread") | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| //! libc's `gettid`, looked up at runtime since glibc < 2.30 does not export it. | ||
|
|
||
| type GetTidFn = extern "C" fn() -> libc::pid_t; | ||
|
|
||
| /// Looks up libc's `gettid`, if it exports one. | ||
| /// | ||
| /// The lookup runs once per process. | ||
| fn gettid_fn() -> Option<GetTidFn> { | ||
| static GETTID: std::sync::OnceLock<Option<GetTidFn>> = std::sync::OnceLock::new(); | ||
|
|
||
| *GETTID.get_or_init(|| { | ||
| // SAFETY: the name is NUL-terminated and `RTLD_DEFAULT` is a valid handle. | ||
| let res: *mut libc::c_void = unsafe { libc::dlsym(libc::RTLD_DEFAULT, c"gettid".as_ptr()) }; | ||
|
|
||
| if res.is_null() { | ||
| return None; | ||
| } | ||
|
|
||
| // SAFETY: libc's `gettid` is `pid_t gettid(void)`, which is what | ||
| // `GetTidFn` declares, and `res` is not null. | ||
| Some(unsafe { std::mem::transmute::<*mut libc::c_void, GetTidFn>(res) }) | ||
| }) | ||
| } | ||
|
|
||
| /// Gets the calling thread's id from libc's `gettid`, if libc exports one. | ||
| pub(super) fn gettid() -> Option<u64> { | ||
| gettid_fn().map(|gettid| gettid() as u64) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| //! Linux-specific OS utilities. | ||
| #![allow(unsafe_code, reason = "need to call system utilities in os code")] | ||
|
|
||
| mod glibc; | ||
|
|
||
| /// Get the current thread's system ID. | ||
| #[inline] | ||
| pub(super) fn gettid() -> u64 { | ||
| fn syscall_gettid() -> u64 { | ||
| // SAFETY: the gettid syscall takes no arguments and touches no memory. | ||
| unsafe { libc::syscall(libc::SYS_gettid) as u64 } | ||
| } | ||
|
|
||
| glibc::gettid().unwrap_or_else(syscall_gettid) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| //! Operating system utilities. | ||
|
|
||
| #[cfg(target_vendor = "apple")] | ||
| mod apple; | ||
| #[cfg(any(target_os = "linux", target_os = "android"))] | ||
| mod linux; | ||
| #[cfg(target_os = "windows")] | ||
| mod windows; | ||
|
|
||
| /// Gets the current thread id as an integer. | ||
| /// | ||
| /// [`Option::None`] if the active thread could not be determined or the | ||
| /// platform doesn't support it. | ||
| /// | ||
| /// Note that a Rust `ThreadId` is actually just a process specific atomic, | ||
| /// completely unrelated to the thread id assigned by the operating system, but | ||
| /// we use the operating system one, at least until they stabilize | ||
| /// <https://doc.rust-lang.org/std/thread/struct.ThreadId.html#method.as_u64> | ||
| #[inline] | ||
| pub(crate) fn gettid() -> Option<u64> { | ||
| #[cfg(target_vendor = "apple")] | ||
| { | ||
| Some(apple::gettid()) | ||
| } | ||
| #[cfg(any(target_os = "linux", target_os = "android"))] | ||
| { | ||
| Some(linux::gettid()) | ||
| } | ||
| #[cfg(target_os = "windows")] | ||
| { | ||
| Some(windows::gettid()) | ||
| } | ||
|
|
||
| #[cfg(not(any( | ||
| target_vendor = "apple", | ||
| target_os = "linux", | ||
| target_os = "android", | ||
| target_os = "windows" | ||
| )))] | ||
| None | ||
| } | ||
|
|
||
| #[cfg(all(test, any(target_os = "linux", target_os = "android")))] | ||
| mod tests { | ||
| use super::*; | ||
|
|
||
| #[test] | ||
| fn gettid_returns_the_kernel_tid() { | ||
| // A new thread, since under `--test-threads=1` this runs on the main | ||
| // thread, whose tid is also the pid. | ||
| let (got, tid) = std::thread::spawn(|| { | ||
| let link = std::fs::read_link("/proc/thread-self").expect("procfs is mounted"); | ||
| let tid: u64 = link | ||
| .file_name() | ||
| .and_then(|name| name.to_str()) | ||
| .and_then(|name| name.parse().ok()) | ||
| .expect("/proc/thread-self ends in the tid"); | ||
|
|
||
| (gettid(), tid) | ||
| }) | ||
| .join() | ||
| .expect("the probe thread does not panic"); | ||
|
|
||
| assert_eq!(got, Some(tid)); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| //! Windows-specific OS utilities. | ||
| #![allow(unsafe_code, reason = "need to call system utilities in os code")] | ||
|
|
||
| #[link(name = "kernel32", kind = "raw-dylib")] | ||
| unsafe extern "system" { | ||
| safe fn GetCurrentThreadId() -> u32; | ||
| } | ||
|
|
||
| /// Get the current system thread id. | ||
| #[inline] | ||
| pub(super) fn gettid() -> u64 { | ||
| GetCurrentThreadId() as _ | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
libc::pthread_threadid_nptakes a pointer-typedpthread_ton Apple, but this call passes the integer0. Rust does not convert that integer into a null pointer, so macOS builds fail with a type mismatch. Passstd::ptr::null_mut()instead.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not true: on Apple, libc defines
pthread_t = crate::uintptr_t(src/unix/bsd/mod.rs:8in libc 0.2.191), so0is ausizeandTest (macos-14)passes.std::ptr::null_mut()is what would fail to compile.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right—my comment was incorrect. With the locked libc 0.2.191 binding, Apple’s
pthread_tisuintptr_t(usize), so0is type-correct here, whilestd::ptr::null_mut()would fail to compile. The macOS CI pass is consistent with that. Please disregard my suggested change; the existing call is correct.