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>
This commit is contained in:
@@ -13,12 +13,14 @@
|
|||||||
use core::prelude::*;
|
use core::prelude::*;
|
||||||
|
|
||||||
use cmp;
|
use cmp;
|
||||||
|
use dynamic_lib::DynamicLibrary;
|
||||||
use ffi::CString;
|
use ffi::CString;
|
||||||
use io;
|
use io;
|
||||||
use libc::consts::os::posix01::PTHREAD_STACK_MIN;
|
use libc::consts::os::posix01::PTHREAD_STACK_MIN;
|
||||||
use libc;
|
use libc;
|
||||||
use mem;
|
use mem;
|
||||||
use ptr;
|
use ptr;
|
||||||
|
use sync::{Once, ONCE_INIT};
|
||||||
use sys::os;
|
use sys::os;
|
||||||
use thunk::Thunk;
|
use thunk::Thunk;
|
||||||
use time::Duration;
|
use time::Duration;
|
||||||
@@ -314,21 +316,30 @@ pub fn sleep(dur: Duration) {
|
|||||||
// is created in an application with big thread-local storage requirements.
|
// is created in an application with big thread-local storage requirements.
|
||||||
// See #6233 for rationale and details.
|
// See #6233 for rationale and details.
|
||||||
//
|
//
|
||||||
// Link weakly to the symbol for compatibility with older versions of glibc.
|
// Use dlsym to get the symbol value at runtime, for compatibility
|
||||||
// Assumes that we've been dynamically linked to libpthread but that is
|
// with older versions of glibc. Assumes that we've been dynamically
|
||||||
// currently always the case. Note that you need to check that the symbol
|
// linked to libpthread but that is currently always the case. We
|
||||||
// is non-null before calling it!
|
// 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")]
|
#[cfg(target_os = "linux")]
|
||||||
fn min_stack_size(attr: *const libc::pthread_attr_t) -> libc::size_t {
|
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;
|
type F = unsafe extern "C" fn(*const libc::pthread_attr_t) -> libc::size_t;
|
||||||
extern {
|
static INIT: Once = ONCE_INIT;
|
||||||
#[linkage = "extern_weak"]
|
static mut __pthread_get_minstack: Option<F> = None;
|
||||||
static __pthread_get_minstack: *const ();
|
|
||||||
|
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));
|
||||||
}
|
}
|
||||||
if __pthread_get_minstack.is_null() {
|
}
|
||||||
PTHREAD_STACK_MIN
|
});
|
||||||
} else {
|
|
||||||
unsafe { mem::transmute::<*const (), F>(__pthread_get_minstack)(attr) }
|
match unsafe { __pthread_get_minstack } {
|
||||||
|
None => PTHREAD_STACK_MIN,
|
||||||
|
Some(f) => unsafe { f(attr) },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user