Skip to content

Commit 28fcdc0

Browse files
committed
rollup merge of #23631: andersk/minstack-dlsym
Linking `__pthread_get_minstack`, even weakly, was causing Debian’s `dpkg-shlibdeps` to detect an unnecessarily strict versioned dependency on libc6. Closes #23628.
2 parents ef07e07 + 737bb30 commit 28fcdc0

File tree

1 file changed

+26
-14
lines changed

1 file changed

+26
-14
lines changed

src/libstd/sys/unix/thread.rs

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@
1313
use core::prelude::*;
1414

1515
use cmp;
16+
use dynamic_lib::DynamicLibrary;
1617
use ffi::CString;
1718
use io;
1819
use libc::consts::os::posix01::PTHREAD_STACK_MIN;
1920
use libc;
2021
use mem;
2122
use ptr;
23+
use sync::{Once, ONCE_INIT};
2224
use sys::os;
2325
use thunk::Thunk;
2426
use time::Duration;
@@ -314,26 +316,36 @@ pub fn sleep(dur: Duration) {
314316
// is created in an application with big thread-local storage requirements.
315317
// See #6233 for rationale and details.
316318
//
317-
// Link weakly to the symbol for compatibility with older versions of glibc.
318-
// Assumes that we've been dynamically linked to libpthread but that is
319-
// currently always the case. Note that you need to check that the symbol
320-
// is non-null before calling it!
319+
// Use dlsym to get the symbol value at runtime, both for
320+
// compatibility with older versions of glibc, and to avoid creating
321+
// dependencies on GLIBC_PRIVATE symbols. Assumes that we've been
322+
// dynamically linked to libpthread but that is currently always the
323+
// case. We previously used weak linkage (under the same assumption),
324+
// but that caused Debian to detect an unnecessarily strict versioned
325+
// dependency on libc6 (#23628).
321326
#[cfg(target_os = "linux")]
322327
fn min_stack_size(attr: *const libc::pthread_attr_t) -> libc::size_t {
323328
type F = unsafe extern "C" fn(*const libc::pthread_attr_t) -> libc::size_t;
324-
extern {
325-
#[linkage = "extern_weak"]
326-
static __pthread_get_minstack: *const ();
327-
}
328-
if __pthread_get_minstack.is_null() {
329-
PTHREAD_STACK_MIN
330-
} else {
331-
unsafe { mem::transmute::<*const (), F>(__pthread_get_minstack)(attr) }
329+
static INIT: Once = ONCE_INIT;
330+
static mut __pthread_get_minstack: Option<F> = None;
331+
332+
INIT.call_once(|| {
333+
let lib = DynamicLibrary::open(None).unwrap();
334+
unsafe {
335+
if let Ok(f) = lib.symbol("__pthread_get_minstack") {
336+
__pthread_get_minstack = Some(mem::transmute::<*const (), F>(f));
337+
}
338+
}
339+
});
340+
341+
match unsafe { __pthread_get_minstack } {
342+
None => PTHREAD_STACK_MIN,
343+
Some(f) => unsafe { f(attr) },
332344
}
333345
}
334346

335-
// __pthread_get_minstack() is marked as weak but extern_weak linkage is
336-
// not supported on OS X, hence this kludge...
347+
// No point in looking up __pthread_get_minstack() on non-glibc
348+
// platforms.
337349
#[cfg(not(target_os = "linux"))]
338350
fn min_stack_size(_: *const libc::pthread_attr_t) -> libc::size_t {
339351
PTHREAD_STACK_MIN

0 commit comments

Comments
 (0)