-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Get __pthread_get_minstack at runtime with dlsym #23631
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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,26 +316,36 @@ 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, both for | ||
// compatibility with older versions of glibc, and to avoid creating | ||
// dependencies on GLIBC_PRIVATE symbols. 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") { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: could use stringify! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nits are welcome. What’s the advantage of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. just makes it explicit that the variable name matches the symbol name There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does it? There’d still be nothing to check that they match. And the variable name isn’t really important; the important thing is that the symbol name matches the glibc name, which we can’t statically enforce. |
||
__pthread_get_minstack = Some(mem::transmute::<*const (), F>(f)); | ||
} | ||
} | ||
}); | ||
|
||
match unsafe { __pthread_get_minstack } { | ||
None => PTHREAD_STACK_MIN, | ||
Some(f) => unsafe { f(attr) }, | ||
} | ||
} | ||
|
||
// __pthread_get_minstack() is marked as weak but extern_weak linkage is | ||
// not supported on OS X, hence this kludge... | ||
// No point in looking up __pthread_get_minstack() on non-glibc | ||
// platforms. | ||
#[cfg(not(target_os = "linux"))] | ||
fn min_stack_size(_: *const libc::pthread_attr_t) -> libc::size_t { | ||
PTHREAD_STACK_MIN | ||
|
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.
since you're removing this could you merge the mac os implementation into this?
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.
I’m not a Mac user; does Rust use glibc on Mac? I figured we shouldn’t waste time looking up
__pthread_get_minstack
on non-glibc.(But yeah, I should update the comment below, if nothing else.)
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.
i guess i'm not sure, just going by this comment: https://github.com/rust-lang/rust/blob/master/src/libstd/sys/unix/thread.rs#L335