Skip to content

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

Merged
merged 3 commits into from
Mar 24, 2015
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 26 additions & 14 deletions src/libstd/sys/unix/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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).
Copy link
Contributor

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?

Copy link
Contributor Author

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.)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#[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") {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: could use stringify!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nits are welcome. What’s the advantage of lib.symbol(stringify!(__pthread_get_minstack))? (Or do you mean something else?)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just makes it explicit that the variable name matches the symbol name

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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
Expand Down