|
13 | 13 | use core::prelude::*;
|
14 | 14 |
|
15 | 15 | use cmp;
|
| 16 | +use dynamic_lib::DynamicLibrary; |
16 | 17 | use ffi::CString;
|
17 | 18 | use io;
|
18 | 19 | use libc::consts::os::posix01::PTHREAD_STACK_MIN;
|
19 | 20 | use libc;
|
20 | 21 | use mem;
|
21 | 22 | use ptr;
|
| 23 | +use sync::{Once, ONCE_INIT}; |
22 | 24 | use sys::os;
|
23 | 25 | use thunk::Thunk;
|
24 | 26 | use time::Duration;
|
@@ -314,21 +316,30 @@ pub fn sleep(dur: Duration) {
|
314 | 316 | // is created in an application with big thread-local storage requirements.
|
315 | 317 | // See #6233 for rationale and details.
|
316 | 318 | //
|
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, for compatibility |
| 320 | +// with older versions of glibc. Assumes that we've been dynamically |
| 321 | +// linked to libpthread but that is currently always the case. We |
| 322 | +// previously used weak linkage (under the same assumption), but that |
| 323 | +// caused Debian to detect an unnecessarily strict versioned |
| 324 | +// dependency on libc6 (#23628). |
321 | 325 | #[cfg(target_os = "linux")]
|
322 | 326 | fn min_stack_size(attr: *const libc::pthread_attr_t) -> libc::size_t {
|
323 | 327 | 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) } |
| 328 | + static INIT: Once = ONCE_INIT; |
| 329 | + static mut __pthread_get_minstack: Option<F> = None; |
| 330 | + |
| 331 | + INIT.call_once(|| { |
| 332 | + let lib = DynamicLibrary::open(None).unwrap(); |
| 333 | + unsafe { |
| 334 | + if let Ok(f) = lib.symbol("__pthread_get_minstack") { |
| 335 | + __pthread_get_minstack = Some(mem::transmute::<*const (), F>(f)); |
| 336 | + } |
| 337 | + } |
| 338 | + }); |
| 339 | + |
| 340 | + match unsafe { __pthread_get_minstack } { |
| 341 | + None => PTHREAD_STACK_MIN, |
| 342 | + Some(f) => unsafe { f(attr) }, |
332 | 343 | }
|
333 | 344 | }
|
334 | 345 |
|
|
0 commit comments