diff options
| author | Anders Kaseorg <andersk@mit.edu> | 2015-03-23 00:58:19 -0400 |
|---|---|---|
| committer | Anders Kaseorg <andersk@mit.edu> | 2015-03-23 01:05:05 -0400 |
| commit | 0090e01f08f7ed564a62fb3cd2e3b652317d39d7 (patch) | |
| tree | 7dc172dd099389d20ca227c6ee52a313151b9fc7 /src/libstd/sys | |
| parent | b0aad7dd4fad8d7e2e2f877a511a637258949597 (diff) | |
| download | rust-0090e01f08f7ed564a62fb3cd2e3b652317d39d7.tar.gz rust-0090e01f08f7ed564a62fb3cd2e3b652317d39d7.zip | |
Get __pthread_get_minstack at runtime with dlsym
Linking __pthread_get_minstack, even weakly, was causing Debian’s dpkg-shlibdeps to detect an unnecessarily strict versioned dependency on libc6. Closes #23628. Signed-off-by: Anders Kaseorg <andersk@mit.edu>
Diffstat (limited to 'src/libstd/sys')
| -rw-r--r-- | src/libstd/sys/unix/thread.rs | 35 |
1 files changed, 23 insertions, 12 deletions
diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index c5f07c6c75a..1d3cb43465b 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -13,12 +13,14 @@ use core::prelude::*; use cmp; +use dynamic_lib::DynamicLibrary; use ffi::CString; use io; use libc::consts::os::posix01::PTHREAD_STACK_MIN; use libc; use mem; use ptr; +use sync::{Once, ONCE_INIT}; use sys::os; use thunk::Thunk; use time::Duration; @@ -314,21 +316,30 @@ pub fn sleep(dur: Duration) { // is created in an application with big thread-local storage requirements. // See #6233 for rationale and details. // -// Link weakly to the symbol for compatibility with older versions of glibc. -// Assumes that we've been dynamically linked to libpthread but that is -// currently always the case. Note that you need to check that the symbol -// is non-null before calling it! +// Use dlsym to get the symbol value at runtime, for compatibility +// with older versions of glibc. Assumes that we've been dynamically +// linked to libpthread but that is currently always the case. We +// previously used weak linkage (under the same assumption), but that +// caused Debian to detect an unnecessarily strict versioned +// dependency on libc6 (#23628). #[cfg(target_os = "linux")] fn min_stack_size(attr: *const libc::pthread_attr_t) -> libc::size_t { type F = unsafe extern "C" fn(*const libc::pthread_attr_t) -> libc::size_t; - extern { - #[linkage = "extern_weak"] - static __pthread_get_minstack: *const (); - } - if __pthread_get_minstack.is_null() { - PTHREAD_STACK_MIN - } else { - unsafe { mem::transmute::<*const (), F>(__pthread_get_minstack)(attr) } + static INIT: Once = ONCE_INIT; + static mut __pthread_get_minstack: Option<F> = None; + + INIT.call_once(|| { + let lib = DynamicLibrary::open(None).unwrap(); + unsafe { + if let Ok(f) = lib.symbol("__pthread_get_minstack") { + __pthread_get_minstack = Some(mem::transmute::<*const (), F>(f)); + } + } + }); + + match unsafe { __pthread_get_minstack } { + None => PTHREAD_STACK_MIN, + Some(f) => unsafe { f(attr) }, } } |
