Rollup merge of #62862 - BaoshanPang:cleanup, r=alexcrichton
code cleanup remove all codes that are not used by vxWorks
This commit is contained in:
commit
ceea0be207
11 changed files with 1 additions and 1042 deletions
|
|
@ -41,36 +41,6 @@ unsafe impl GlobalAlloc for System {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "android",
|
||||
target_os = "hermit",
|
||||
target_os = "redox",
|
||||
target_os = "solaris"))]
|
||||
#[inline]
|
||||
unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
|
||||
// On android we currently target API level 9 which unfortunately
|
||||
// doesn't have the `posix_memalign` API used below. Instead we use
|
||||
// `memalign`, but this unfortunately has the property on some systems
|
||||
// where the memory returned cannot be deallocated by `free`!
|
||||
//
|
||||
// Upon closer inspection, however, this appears to work just fine with
|
||||
// Android, so for this platform we should be fine to call `memalign`
|
||||
// (which is present in API level 9). Some helpful references could
|
||||
// possibly be chromium using memalign [1], attempts at documenting that
|
||||
// memalign + free is ok [2] [3], or the current source of chromium
|
||||
// which still uses memalign on android [4].
|
||||
//
|
||||
// [1]: https://codereview.chromium.org/10796020/
|
||||
// [2]: https://code.google.com/p/android/issues/detail?id=35391
|
||||
// [3]: https://bugs.chromium.org/p/chromium/issues/detail?id=138579
|
||||
// [4]: https://chromium.googlesource.com/chromium/src/base/+/master/
|
||||
// /memory/aligned_memory.cc
|
||||
libc::memalign(layout.align(), layout.size()) as *mut u8
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "android",
|
||||
target_os = "hermit",
|
||||
target_os = "redox",
|
||||
target_os = "solaris")))]
|
||||
#[inline]
|
||||
unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
|
||||
let mut out = ptr::null_mut();
|
||||
|
|
|
|||
|
|
@ -1,160 +0,0 @@
|
|||
//! Android ABI-compatibility module
|
||||
//!
|
||||
//! The ABI of Android has changed quite a bit over time, and libstd attempts to
|
||||
//! be both forwards and backwards compatible as much as possible. We want to
|
||||
//! always work with the most recent version of Android, but we also want to
|
||||
//! work with older versions of Android for whenever projects need to.
|
||||
//!
|
||||
//! Our current minimum supported Android version is `android-9`, e.g., Android
|
||||
//! with API level 9. We then in theory want to work on that and all future
|
||||
//! versions of Android!
|
||||
//!
|
||||
//! Some of the detection here is done at runtime via `dlopen` and
|
||||
//! introspection. Other times no detection is performed at all and we just
|
||||
//! provide a fallback implementation as some versions of Android we support
|
||||
//! don't have the function.
|
||||
//!
|
||||
//! You'll find more details below about why each compatibility shim is needed.
|
||||
|
||||
#![cfg(target_os = "android")]
|
||||
|
||||
use libc::{c_int, c_void, sighandler_t, size_t, ssize_t};
|
||||
use libc::{ftruncate, pread, pwrite};
|
||||
|
||||
use crate::io;
|
||||
use super::{cvt, cvt_r};
|
||||
|
||||
// The `log2` and `log2f` functions apparently appeared in android-18, or at
|
||||
// least you can see they're not present in the android-17 header [1] and they
|
||||
// are present in android-18 [2].
|
||||
//
|
||||
// [1]: https://chromium.googlesource.com/android_tools/+/20ee6d20/ndk/platforms
|
||||
// /android-17/arch-arm/usr/include/math.h
|
||||
// [2]: https://chromium.googlesource.com/android_tools/+/20ee6d20/ndk/platforms
|
||||
// /android-18/arch-arm/usr/include/math.h
|
||||
//
|
||||
// Note that these shims are likely less precise than directly calling `log2`,
|
||||
// but hopefully that should be enough for now...
|
||||
//
|
||||
// Note that mathematically, for any arbitrary `y`:
|
||||
//
|
||||
// log_2(x) = log_y(x) / log_y(2)
|
||||
// = log_y(x) / (1 / log_2(y))
|
||||
// = log_y(x) * log_2(y)
|
||||
//
|
||||
// Hence because `ln` (log_e) is available on all Android we just choose `y = e`
|
||||
// and get:
|
||||
//
|
||||
// log_2(x) = ln(x) * log_2(e)
|
||||
|
||||
#[cfg(not(test))]
|
||||
pub fn log2f32(f: f32) -> f32 {
|
||||
f.ln() * crate::f32::consts::LOG2_E
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
pub fn log2f64(f: f64) -> f64 {
|
||||
f.ln() * crate::f64::consts::LOG2_E
|
||||
}
|
||||
|
||||
// Back in the day [1] the `signal` function was just an inline wrapper
|
||||
// around `bsd_signal`, but starting in API level android-20 the `signal`
|
||||
// symbols was introduced [2]. Finally, in android-21 the API `bsd_signal` was
|
||||
// removed [3].
|
||||
//
|
||||
// Basically this means that if we want to be binary compatible with multiple
|
||||
// Android releases (oldest being 9 and newest being 21) then we need to check
|
||||
// for both symbols and not actually link against either.
|
||||
//
|
||||
// [1]: https://chromium.googlesource.com/android_tools/+/20ee6d20/ndk/platforms
|
||||
// /android-18/arch-arm/usr/include/signal.h
|
||||
// [2]: https://chromium.googlesource.com/android_tools/+/fbd420/ndk_experimental
|
||||
// /platforms/android-20/arch-arm
|
||||
// /usr/include/signal.h
|
||||
// [3]: https://chromium.googlesource.com/android_tools/+/20ee6d/ndk/platforms
|
||||
// /android-21/arch-arm/usr/include/signal.h
|
||||
pub unsafe fn signal(signum: c_int, handler: sighandler_t) -> sighandler_t {
|
||||
weak!(fn signal(c_int, sighandler_t) -> sighandler_t);
|
||||
weak!(fn bsd_signal(c_int, sighandler_t) -> sighandler_t);
|
||||
|
||||
let f = signal.get().or_else(|| bsd_signal.get());
|
||||
let f = f.expect("neither `signal` nor `bsd_signal` symbols found");
|
||||
f(signum, handler)
|
||||
}
|
||||
|
||||
// The `ftruncate64` symbol apparently appeared in android-12, so we do some
|
||||
// dynamic detection to see if we can figure out whether `ftruncate64` exists.
|
||||
//
|
||||
// If it doesn't we just fall back to `ftruncate`, generating an error for
|
||||
// too-large values.
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
pub fn ftruncate64(fd: c_int, size: u64) -> io::Result<()> {
|
||||
weak!(fn ftruncate64(c_int, i64) -> c_int);
|
||||
|
||||
unsafe {
|
||||
match ftruncate64.get() {
|
||||
Some(f) => cvt_r(|| f(fd, size as i64)).map(|_| ()),
|
||||
None => {
|
||||
if size > i32::max_value() as u64 {
|
||||
Err(io::Error::new(io::ErrorKind::InvalidInput,
|
||||
"cannot truncate >2GB"))
|
||||
} else {
|
||||
cvt_r(|| ftruncate(fd, size as i32)).map(|_| ())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
pub fn ftruncate64(fd: c_int, size: u64) -> io::Result<()> {
|
||||
unsafe {
|
||||
cvt_r(|| ftruncate(fd, size as i64)).map(|_| ())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
pub unsafe fn cvt_pread64(fd: c_int, buf: *mut c_void, count: size_t, offset: i64)
|
||||
-> io::Result<ssize_t>
|
||||
{
|
||||
use crate::convert::TryInto;
|
||||
weak!(fn pread64(c_int, *mut c_void, size_t, i64) -> ssize_t);
|
||||
pread64.get().map(|f| cvt(f(fd, buf, count, offset))).unwrap_or_else(|| {
|
||||
if let Ok(o) = offset.try_into() {
|
||||
cvt(pread(fd, buf, count, o))
|
||||
} else {
|
||||
Err(io::Error::new(io::ErrorKind::InvalidInput,
|
||||
"cannot pread >2GB"))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
pub unsafe fn cvt_pwrite64(fd: c_int, buf: *const c_void, count: size_t, offset: i64)
|
||||
-> io::Result<ssize_t>
|
||||
{
|
||||
use crate::convert::TryInto;
|
||||
weak!(fn pwrite64(c_int, *const c_void, size_t, i64) -> ssize_t);
|
||||
pwrite64.get().map(|f| cvt(f(fd, buf, count, offset))).unwrap_or_else(|| {
|
||||
if let Ok(o) = offset.try_into() {
|
||||
cvt(pwrite(fd, buf, count, o))
|
||||
} else {
|
||||
Err(io::Error::new(io::ErrorKind::InvalidInput,
|
||||
"cannot pwrite >2GB"))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
pub unsafe fn cvt_pread64(fd: c_int, buf: *mut c_void, count: size_t, offset: i64)
|
||||
-> io::Result<ssize_t>
|
||||
{
|
||||
cvt(pread(fd, buf, count, offset))
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
pub unsafe fn cvt_pwrite64(fd: c_int, buf: *const c_void, count: size_t, offset: i64)
|
||||
-> io::Result<ssize_t>
|
||||
{
|
||||
cvt(pwrite(fd, buf, count, offset))
|
||||
}
|
||||
|
|
@ -62,10 +62,6 @@ impl Condvar {
|
|||
// where we configure condition variable to use monotonic clock (instead of
|
||||
// default system clock). This approach avoids all problems that result
|
||||
// from changes made to the system time.
|
||||
#[cfg(not(any(target_os = "macos",
|
||||
target_os = "ios",
|
||||
target_os = "android",
|
||||
target_os = "hermit")))]
|
||||
pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
|
||||
use crate::mem;
|
||||
|
||||
|
|
@ -92,78 +88,9 @@ impl Condvar {
|
|||
}
|
||||
|
||||
|
||||
// This implementation is modeled after libcxx's condition_variable
|
||||
// https://github.com/llvm-mirror/libcxx/blob/release_35/src/condition_variable.cpp#L46
|
||||
// https://github.com/llvm-mirror/libcxx/blob/release_35/include/__mutex_base#L367
|
||||
#[cfg(any(target_os = "macos", target_os = "ios", target_os = "android", target_os = "hermit"))]
|
||||
pub unsafe fn wait_timeout(&self, mutex: &Mutex, mut dur: Duration) -> bool {
|
||||
use crate::ptr;
|
||||
use crate::time::Instant;
|
||||
|
||||
// 1000 years
|
||||
let max_dur = Duration::from_secs(1000 * 365 * 86400);
|
||||
|
||||
if dur > max_dur {
|
||||
// OSX implementation of `pthread_cond_timedwait` is buggy
|
||||
// with super long durations. When duration is greater than
|
||||
// 0x100_0000_0000_0000 seconds, `pthread_cond_timedwait`
|
||||
// in macOS Sierra return error 316.
|
||||
//
|
||||
// This program demonstrates the issue:
|
||||
// https://gist.github.com/stepancheg/198db4623a20aad2ad7cddb8fda4a63c
|
||||
//
|
||||
// To work around this issue, and possible bugs of other OSes, timeout
|
||||
// is clamped to 1000 years, which is allowable per the API of `wait_timeout`
|
||||
// because of spurious wakeups.
|
||||
|
||||
dur = max_dur;
|
||||
}
|
||||
|
||||
// First, figure out what time it currently is, in both system and
|
||||
// stable time. pthread_cond_timedwait uses system time, but we want to
|
||||
// report timeout based on stable time.
|
||||
let mut sys_now = libc::timeval { tv_sec: 0, tv_usec: 0 };
|
||||
let stable_now = Instant::now();
|
||||
let r = libc::gettimeofday(&mut sys_now, ptr::null_mut());
|
||||
debug_assert_eq!(r, 0);
|
||||
|
||||
let nsec = dur.subsec_nanos() as libc::c_long +
|
||||
(sys_now.tv_usec * 1000) as libc::c_long;
|
||||
let extra = (nsec / 1_000_000_000) as libc::time_t;
|
||||
let nsec = nsec % 1_000_000_000;
|
||||
let seconds = saturating_cast_to_time_t(dur.as_secs());
|
||||
|
||||
let timeout = sys_now.tv_sec.checked_add(extra).and_then(|s| {
|
||||
s.checked_add(seconds)
|
||||
}).map(|s| {
|
||||
libc::timespec { tv_sec: s, tv_nsec: nsec }
|
||||
}).unwrap_or(TIMESPEC_MAX);
|
||||
|
||||
// And wait!
|
||||
let r = libc::pthread_cond_timedwait(self.inner.get(), mutex::raw(mutex),
|
||||
&timeout);
|
||||
debug_assert!(r == libc::ETIMEDOUT || r == 0);
|
||||
|
||||
// ETIMEDOUT is not a totally reliable method of determining timeout due
|
||||
// to clock shifts, so do the check ourselves
|
||||
stable_now.elapsed() < dur
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(not(target_os = "dragonfly"))]
|
||||
pub unsafe fn destroy(&self) {
|
||||
let r = libc::pthread_cond_destroy(self.inner.get());
|
||||
debug_assert_eq!(r, 0);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(target_os = "dragonfly")]
|
||||
pub unsafe fn destroy(&self) {
|
||||
let r = libc::pthread_cond_destroy(self.inner.get());
|
||||
// On DragonFly pthread_cond_destroy() returns EINVAL if called on
|
||||
// a condvar that was just initialized with
|
||||
// libc::PTHREAD_COND_INITIALIZER. Once it is used or
|
||||
// pthread_cond_init() is called, this behaviour no longer occurs.
|
||||
debug_assert!(r == 0 || r == libc::EINVAL);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,16 +5,6 @@
|
|||
#[cfg(unix)]
|
||||
use libc;
|
||||
|
||||
// FIXME(#43348): Make libc adapt #[doc(cfg(...))] so we don't need these fake definitions here?
|
||||
#[cfg(not(unix))]
|
||||
mod libc {
|
||||
pub use libc::c_int;
|
||||
pub type socklen_t = u32;
|
||||
pub struct sockaddr;
|
||||
#[derive(Clone)]
|
||||
pub struct sockaddr_un;
|
||||
}
|
||||
|
||||
use crate::ascii;
|
||||
use crate::ffi::OsStr;
|
||||
use crate::fmt;
|
||||
|
|
@ -29,15 +19,6 @@ use crate::sys::{self, cvt};
|
|||
use crate::sys::net::Socket;
|
||||
use crate::sys_common::{self, AsInner, FromInner, IntoInner};
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "android",
|
||||
target_os = "dragonfly", target_os = "freebsd",
|
||||
target_os = "openbsd", target_os = "netbsd",
|
||||
target_os = "haiku"))]
|
||||
use libc::MSG_NOSIGNAL;
|
||||
#[cfg(not(any(target_os = "linux", target_os = "android",
|
||||
target_os = "dragonfly", target_os = "freebsd",
|
||||
target_os = "openbsd", target_os = "netbsd",
|
||||
target_os = "haiku")))]
|
||||
const MSG_NOSIGNAL: libc::c_int = 0x0;
|
||||
|
||||
fn sun_path_offset(addr: &libc::sockaddr_un) -> usize {
|
||||
|
|
@ -202,13 +183,7 @@ impl SocketAddr {
|
|||
let len = self.len as usize - sun_path_offset(&self.addr);
|
||||
let path = unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.addr.sun_path) };
|
||||
|
||||
// macOS seems to return a len of 16 and a zeroed sun_path for unnamed addresses
|
||||
if len == 0
|
||||
|| (cfg!(not(any(target_os = "linux", target_os = "android")))
|
||||
&& self.addr.sun_path[0] == 0)
|
||||
{
|
||||
AddressKind::Unnamed
|
||||
} else if self.addr.sun_path[0] == 0 {
|
||||
if self.addr.sun_path[0] == 0 {
|
||||
AddressKind::Abstract(&path[1..len])
|
||||
} else {
|
||||
AddressKind::Pathname(OsStr::from_bytes(&path[..len - 1]).as_ref())
|
||||
|
|
|
|||
|
|
@ -1,469 +0,0 @@
|
|||
macro_rules! unimpl {
|
||||
() => (return Err(io::Error::new(io::ErrorKind::Other, "No networking available on L4Re."));)
|
||||
}
|
||||
|
||||
pub mod net {
|
||||
#![allow(warnings)]
|
||||
use crate::fmt;
|
||||
use crate::io::{self, IoVec, IoVecMut};
|
||||
use crate::net::{SocketAddr, Shutdown, Ipv4Addr, Ipv6Addr};
|
||||
use crate::sys_common::{AsInner, FromInner, IntoInner};
|
||||
use crate::sys::fd::FileDesc;
|
||||
use crate::time::Duration;
|
||||
use crate::convert::TryFrom;
|
||||
|
||||
#[allow(unused_extern_crates)]
|
||||
pub extern crate libc as netc;
|
||||
|
||||
pub struct Socket(FileDesc);
|
||||
impl Socket {
|
||||
pub fn new(_: &SocketAddr, _: libc::c_int) -> io::Result<Socket> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn new_raw(_: libc::c_int, _: libc::c_int) -> io::Result<Socket> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn new_pair(_: libc::c_int, _: libc::c_int) -> io::Result<(Socket, Socket)> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn connect_timeout(&self, _: &SocketAddr, _: Duration) -> io::Result<()> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn accept(&self, _: *mut libc::sockaddr, _: *mut libc::socklen_t)
|
||||
-> io::Result<Socket> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn duplicate(&self) -> io::Result<Socket> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn read(&self, _: &mut [u8]) -> io::Result<usize> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn read_vectored(&self, _: &mut [IoVecMut<'_>]) -> io::Result<usize> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn write(&self, _: &[u8]) -> io::Result<usize> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn write_vectored(&self, _: &[IoVec<'_>]) -> io::Result<usize> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn set_timeout(&self, _: Option<Duration>, _: libc::c_int) -> io::Result<()> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn timeout(&self, _: libc::c_int) -> io::Result<Option<Duration>> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn shutdown(&self, _: Shutdown) -> io::Result<()> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn set_nodelay(&self, _: bool) -> io::Result<()> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn nodelay(&self) -> io::Result<bool> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
|
||||
unimpl!();
|
||||
}
|
||||
}
|
||||
|
||||
impl AsInner<libc::c_int> for Socket {
|
||||
fn as_inner(&self) -> &libc::c_int { self.0.as_inner() }
|
||||
}
|
||||
|
||||
impl FromInner<libc::c_int> for Socket {
|
||||
fn from_inner(fd: libc::c_int) -> Socket { Socket(FileDesc::new(fd)) }
|
||||
}
|
||||
|
||||
impl IntoInner<libc::c_int> for Socket {
|
||||
fn into_inner(self) -> libc::c_int { self.0.into_raw() }
|
||||
}
|
||||
|
||||
pub struct TcpStream {
|
||||
inner: Socket,
|
||||
}
|
||||
|
||||
impl TcpStream {
|
||||
pub fn connect(_: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn connect_timeout(_: &SocketAddr, _: Duration) -> io::Result<TcpStream> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn socket(&self) -> &Socket { &self.inner }
|
||||
|
||||
pub fn into_socket(self) -> Socket { self.inner }
|
||||
|
||||
pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn read(&self, _: &mut [u8]) -> io::Result<usize> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn read_vectored(&self, _: &mut [IoVecMut<'_>]) -> io::Result<usize> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn write(&self, _: &[u8]) -> io::Result<usize> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn write_vectored(&self, _: &[IoVec<'_>]) -> io::Result<usize> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn shutdown(&self, _: Shutdown) -> io::Result<()> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn duplicate(&self) -> io::Result<TcpStream> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn set_nodelay(&self, _: bool) -> io::Result<()> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn nodelay(&self) -> io::Result<bool> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn set_ttl(&self, _: u32) -> io::Result<()> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn ttl(&self) -> io::Result<u32> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
|
||||
unimpl!();
|
||||
}
|
||||
}
|
||||
|
||||
impl FromInner<Socket> for TcpStream {
|
||||
fn from_inner(socket: Socket) -> TcpStream {
|
||||
TcpStream { inner: socket }
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for TcpStream {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "No networking support available on L4Re")
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TcpListener {
|
||||
inner: Socket,
|
||||
}
|
||||
|
||||
impl TcpListener {
|
||||
pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn socket(&self) -> &Socket { &self.inner }
|
||||
|
||||
pub fn into_socket(self) -> Socket { self.inner }
|
||||
|
||||
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn duplicate(&self) -> io::Result<TcpListener> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn set_ttl(&self, _: u32) -> io::Result<()> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn ttl(&self) -> io::Result<u32> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn set_only_v6(&self, _: bool) -> io::Result<()> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn only_v6(&self) -> io::Result<bool> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
|
||||
unimpl!();
|
||||
}
|
||||
}
|
||||
|
||||
impl FromInner<Socket> for TcpListener {
|
||||
fn from_inner(socket: Socket) -> TcpListener {
|
||||
TcpListener { inner: socket }
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for TcpListener {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "No networking support available on L4Re.")
|
||||
}
|
||||
}
|
||||
|
||||
pub struct UdpSocket {
|
||||
inner: Socket,
|
||||
}
|
||||
|
||||
impl UdpSocket {
|
||||
pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn socket(&self) -> &Socket { &self.inner }
|
||||
|
||||
pub fn into_socket(self) -> Socket { self.inner }
|
||||
|
||||
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn send_to(&self, _: &[u8], _: &SocketAddr) -> io::Result<usize> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn duplicate(&self) -> io::Result<UdpSocket> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn set_broadcast(&self, _: bool) -> io::Result<()> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn broadcast(&self) -> io::Result<bool> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn set_multicast_loop_v4(&self, _: bool) -> io::Result<()> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn multicast_loop_v4(&self) -> io::Result<bool> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn set_multicast_ttl_v4(&self, _: u32) -> io::Result<()> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn set_multicast_loop_v6(&self, _: bool) -> io::Result<()> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn multicast_loop_v6(&self) -> io::Result<bool> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr)
|
||||
-> io::Result<()> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32)
|
||||
-> io::Result<()> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr)
|
||||
-> io::Result<()> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32)
|
||||
-> io::Result<()> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn set_ttl(&self, _: u32) -> io::Result<()> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn ttl(&self) -> io::Result<u32> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn recv(&self, _: &mut [u8]) -> io::Result<usize> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn send(&self, _: &[u8]) -> io::Result<usize> {
|
||||
unimpl!();
|
||||
}
|
||||
|
||||
pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> {
|
||||
unimpl!();
|
||||
}
|
||||
}
|
||||
|
||||
impl FromInner<Socket> for UdpSocket {
|
||||
fn from_inner(socket: Socket) -> UdpSocket {
|
||||
UdpSocket { inner: socket }
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for UdpSocket {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "No networking support on L4Re available.")
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LookupHost {
|
||||
original: *mut libc::addrinfo,
|
||||
cur: *mut libc::addrinfo,
|
||||
}
|
||||
|
||||
impl Iterator for LookupHost {
|
||||
type Item = SocketAddr;
|
||||
fn next(&mut self) -> Option<SocketAddr> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl LookupHost {
|
||||
pub fn port(&self) -> u16 {
|
||||
unimpl!();
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Sync for LookupHost {}
|
||||
unsafe impl Send for LookupHost {}
|
||||
|
||||
|
||||
impl TryFrom<&str> for LookupHost {
|
||||
type Error = io::Error;
|
||||
|
||||
fn try_from(_v: &str) -> io::Result<LookupHost> {
|
||||
unimpl!();
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> TryFrom<(&'a str, u16)> for LookupHost {
|
||||
type Error = io::Error;
|
||||
|
||||
fn try_from(_v: (&'a str, u16)) -> io::Result<LookupHost> {
|
||||
unimpl!();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -16,25 +16,6 @@ pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> {
|
|||
}
|
||||
|
||||
pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> {
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn memrchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
|
||||
// GNU's memrchr() will - unlike memchr() - error if haystack is empty.
|
||||
if haystack.is_empty() {return None}
|
||||
let p = unsafe {
|
||||
libc::memrchr(
|
||||
haystack.as_ptr() as *const libc::c_void,
|
||||
needle as libc::c_int,
|
||||
haystack.len())
|
||||
};
|
||||
if p.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(p as usize - (haystack.as_ptr() as usize))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
fn memrchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
|
||||
core::slice::memchr::memrchr(needle, haystack)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,14 +7,8 @@ pub use crate::os::vxworks as platform;
|
|||
pub use self::rand::hashmap_random_keys;
|
||||
pub use libc::strlen;
|
||||
|
||||
#[macro_use]
|
||||
pub mod weak;
|
||||
|
||||
pub mod alloc;
|
||||
pub mod args;
|
||||
pub mod android;
|
||||
//#[cfg(feature = "backtrace")]
|
||||
//pub mod backtrace;
|
||||
pub mod cmath;
|
||||
pub mod condvar;
|
||||
pub mod env;
|
||||
|
|
@ -25,12 +19,7 @@ pub mod fs;
|
|||
pub mod memchr;
|
||||
pub mod io;
|
||||
pub mod mutex;
|
||||
#[cfg(not(target_os = "l4re"))]
|
||||
pub mod net;
|
||||
#[cfg(target_os = "l4re")]
|
||||
mod l4re;
|
||||
#[cfg(target_os = "l4re")]
|
||||
pub use self::l4re::net;
|
||||
pub mod os;
|
||||
pub mod path;
|
||||
pub mod pipe;
|
||||
|
|
@ -61,9 +50,6 @@ pub fn init() {
|
|||
unsafe fn reset_sigpipe() { }
|
||||
}
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
pub use crate::sys::android::signal;
|
||||
#[cfg(not(target_os = "android"))]
|
||||
pub use libc::signal;
|
||||
|
||||
pub fn decode_error_kind(errno: i32) -> ErrorKind {
|
||||
|
|
|
|||
|
|
@ -58,19 +58,6 @@ impl Socket {
|
|||
|
||||
pub fn new_raw(fam: c_int, ty: c_int) -> io::Result<Socket> {
|
||||
unsafe {
|
||||
// On linux we first attempt to pass the SOCK_CLOEXEC flag to
|
||||
// atomically create the socket and set it as CLOEXEC. Support for
|
||||
// this option, however, was added in 2.6.27, and we still support
|
||||
// 2.6.18 as a kernel, so if the returned error is EINVAL we
|
||||
// fallthrough to the fallback.
|
||||
if cfg!(target_os = "linux") {
|
||||
match cvt(libc::socket(fam, ty | SOCK_CLOEXEC, 0)) {
|
||||
Ok(fd) => return Ok(Socket(FileDesc::new(fd))),
|
||||
Err(ref e) if e.raw_os_error() == Some(libc::EINVAL) => {}
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
let fd = cvt(libc::socket(fam, ty, 0))?;
|
||||
let fd = FileDesc::new(fd);
|
||||
fd.set_cloexec()?;
|
||||
|
|
|
|||
|
|
@ -422,46 +422,12 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
// Android with api less than 21 define sig* functions inline, so it is not
|
||||
// available for dynamic link. Implementing sigemptyset and sigaddset allow us
|
||||
// to support older Android version (independent of libc version).
|
||||
// The following implementations are based on https://git.io/vSkNf
|
||||
|
||||
#[cfg(not(target_os = "android"))]
|
||||
extern {
|
||||
#[cfg_attr(target_os = "netbsd", link_name = "__sigemptyset14")]
|
||||
fn sigemptyset(set: *mut libc::sigset_t) -> libc::c_int;
|
||||
|
||||
#[cfg_attr(target_os = "netbsd", link_name = "__sigaddset14")]
|
||||
fn sigaddset(set: *mut libc::sigset_t, signum: libc::c_int) -> libc::c_int;
|
||||
}
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
unsafe fn sigemptyset(set: *mut libc::sigset_t) -> libc::c_int {
|
||||
libc::memset(set as *mut _, 0, mem::size_of::<libc::sigset_t>());
|
||||
return 0;
|
||||
}
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
unsafe fn sigaddset(set: *mut libc::sigset_t, signum: libc::c_int) -> libc::c_int {
|
||||
use crate::slice;
|
||||
|
||||
let raw = slice::from_raw_parts_mut(set as *mut u8, mem::size_of::<libc::sigset_t>());
|
||||
let bit = (signum - 1) as usize;
|
||||
raw[bit / 8] |= 1 << (bit % 8);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// See #14232 for more information, but it appears that signal delivery to a
|
||||
// newly spawned process may just be raced in the macOS, so to prevent this
|
||||
// test from being flaky we ignore it on macOS.
|
||||
#[test]
|
||||
#[cfg_attr(target_os = "macos", ignore)]
|
||||
// When run under our current QEMU emulation test suite this test fails,
|
||||
// although the reason isn't very clear as to why. For now this test is
|
||||
// ignored there.
|
||||
#[cfg_attr(target_arch = "arm", ignore)]
|
||||
#[cfg_attr(target_arch = "aarch64", ignore)]
|
||||
fn test_process_mask() {
|
||||
unsafe {
|
||||
// Test to make sure that a signal mask does not get inherited.
|
||||
|
|
|
|||
|
|
@ -23,174 +23,6 @@ impl Drop for Handler {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "linux",
|
||||
target_os = "macos",
|
||||
target_os = "bitrig",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "solaris",
|
||||
all(target_os = "netbsd", not(target_vendor = "rumprun")),
|
||||
target_os = "openbsd"))]
|
||||
mod imp {
|
||||
use super::Handler;
|
||||
use crate::mem;
|
||||
use crate::ptr;
|
||||
|
||||
use libc::{sigaltstack, SIGSTKSZ, SS_DISABLE};
|
||||
use libc::{sigaction, SIGBUS, SIG_DFL,
|
||||
SA_SIGINFO, SA_ONSTACK, sighandler_t};
|
||||
use libc::{mmap, munmap};
|
||||
use libc::{SIGSEGV, PROT_READ, PROT_WRITE, MAP_PRIVATE, MAP_ANON};
|
||||
use libc::MAP_FAILED;
|
||||
|
||||
use crate::sys_common::thread_info;
|
||||
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
unsafe fn siginfo_si_addr(info: *mut libc::siginfo_t) -> usize {
|
||||
#[repr(C)]
|
||||
struct siginfo_t {
|
||||
a: [libc::c_int; 3], // si_signo, si_errno, si_code
|
||||
si_addr: *mut libc::c_void,
|
||||
}
|
||||
|
||||
(*(info as *const siginfo_t)).si_addr as usize
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "linux", target_os = "android")))]
|
||||
unsafe fn siginfo_si_addr(info: *mut libc::siginfo_t) -> usize {
|
||||
(*info).si_addr as usize
|
||||
}
|
||||
|
||||
// Signal handler for the SIGSEGV and SIGBUS handlers. We've got guard pages
|
||||
// (unmapped pages) at the end of every thread's stack, so if a thread ends
|
||||
// up running into the guard page it'll trigger this handler. We want to
|
||||
// detect these cases and print out a helpful error saying that the stack
|
||||
// has overflowed. All other signals, however, should go back to what they
|
||||
// were originally supposed to do.
|
||||
//
|
||||
// This handler currently exists purely to print an informative message
|
||||
// whenever a thread overflows its stack. We then abort to exit and
|
||||
// indicate a crash, but to avoid a misleading SIGSEGV that might lead
|
||||
// users to believe that unsafe code has accessed an invalid pointer; the
|
||||
// SIGSEGV encountered when overflowing the stack is expected and
|
||||
// well-defined.
|
||||
//
|
||||
// If this is not a stack overflow, the handler un-registers itself and
|
||||
// then returns (to allow the original signal to be delivered again).
|
||||
// Returning from this kind of signal handler is technically not defined
|
||||
// to work when reading the POSIX spec strictly, but in practice it turns
|
||||
// out many large systems and all implementations allow returning from a
|
||||
// signal handler to work. For a more detailed explanation see the
|
||||
// comments on #26458.
|
||||
unsafe extern fn signal_handler(signum: libc::c_int,
|
||||
info: *mut libc::siginfo_t,
|
||||
_data: *mut libc::c_void) {
|
||||
use crate::sys_common::util::report_overflow;
|
||||
|
||||
let guard = thread_info::stack_guard().unwrap_or(0..0);
|
||||
let addr = siginfo_si_addr(info);
|
||||
|
||||
// If the faulting address is within the guard page, then we print a
|
||||
// message saying so and abort.
|
||||
if guard.start <= addr && addr < guard.end {
|
||||
report_overflow();
|
||||
rtabort!("stack overflow");
|
||||
} else {
|
||||
// Unregister ourselves by reverting back to the default behavior.
|
||||
let mut action: sigaction = mem::zeroed();
|
||||
action.sa_sigaction = SIG_DFL;
|
||||
sigaction(signum, &action, ptr::null_mut());
|
||||
|
||||
// See comment above for why this function returns.
|
||||
}
|
||||
}
|
||||
|
||||
static mut MAIN_ALTSTACK: *mut libc::c_void = ptr::null_mut();
|
||||
|
||||
pub unsafe fn init() {
|
||||
let mut action: sigaction = mem::zeroed();
|
||||
action.sa_flags = SA_SIGINFO | SA_ONSTACK;
|
||||
action.sa_sigaction = signal_handler as sighandler_t;
|
||||
sigaction(SIGSEGV, &action, ptr::null_mut());
|
||||
sigaction(SIGBUS, &action, ptr::null_mut());
|
||||
|
||||
let handler = make_handler();
|
||||
MAIN_ALTSTACK = handler._data;
|
||||
mem::forget(handler);
|
||||
}
|
||||
|
||||
pub unsafe fn cleanup() {
|
||||
Handler { _data: MAIN_ALTSTACK };
|
||||
}
|
||||
|
||||
unsafe fn get_stackp() -> *mut libc::c_void {
|
||||
let stackp = mmap(ptr::null_mut(),
|
||||
SIGSTKSZ,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANON,
|
||||
-1,
|
||||
0);
|
||||
if stackp == MAP_FAILED {
|
||||
panic!("failed to allocate an alternative stack");
|
||||
}
|
||||
stackp
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "linux",
|
||||
target_os = "macos",
|
||||
target_os = "bitrig",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
target_os = "solaris"))]
|
||||
unsafe fn get_stack() -> libc::stack_t {
|
||||
libc::stack_t { ss_sp: get_stackp(), ss_flags: 0, ss_size: SIGSTKSZ }
|
||||
}
|
||||
|
||||
#[cfg(target_os = "dragonfly")]
|
||||
unsafe fn get_stack() -> libc::stack_t {
|
||||
libc::stack_t { ss_sp: get_stackp() as *mut i8, ss_flags: 0, ss_size: SIGSTKSZ }
|
||||
}
|
||||
|
||||
pub unsafe fn make_handler() -> Handler {
|
||||
let mut stack = mem::zeroed();
|
||||
sigaltstack(ptr::null(), &mut stack);
|
||||
// Configure alternate signal stack, if one is not already set.
|
||||
if stack.ss_flags & SS_DISABLE != 0 {
|
||||
stack = get_stack();
|
||||
sigaltstack(&stack, ptr::null_mut());
|
||||
Handler { _data: stack.ss_sp as *mut libc::c_void }
|
||||
} else {
|
||||
Handler { _data: ptr::null_mut() }
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn drop_handler(handler: &mut Handler) {
|
||||
if !handler._data.is_null() {
|
||||
let stack = libc::stack_t {
|
||||
ss_sp: ptr::null_mut(),
|
||||
ss_flags: SS_DISABLE,
|
||||
// Workaround for bug in macOS implementation of sigaltstack
|
||||
// UNIX2003 which returns ENOMEM when disabling a stack while
|
||||
// passing ss_size smaller than MINSIGSTKSZ. According to POSIX
|
||||
// both ss_sp and ss_size should be ignored in this case.
|
||||
ss_size: SIGSTKSZ,
|
||||
};
|
||||
sigaltstack(&stack, ptr::null_mut());
|
||||
munmap(handler._data, SIGSTKSZ);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "linux",
|
||||
target_os = "macos",
|
||||
target_os = "bitrig",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "solaris",
|
||||
all(target_os = "netbsd", not(target_vendor = "rumprun")),
|
||||
target_os = "openbsd")))]
|
||||
mod imp {
|
||||
use crate::ptr;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
//use crate::boxed::FnBox;
|
||||
use crate::cmp;
|
||||
use crate::ffi::CStr;
|
||||
use crate::io;
|
||||
|
|
@ -9,10 +8,7 @@ use crate::time::Duration;
|
|||
|
||||
use crate::sys_common::thread::*;
|
||||
|
||||
#[cfg(not(target_os = "l4re"))]
|
||||
pub const DEFAULT_MIN_STACK_SIZE: usize = 2 * 1024 * 1024;
|
||||
#[cfg(target_os = "l4re")]
|
||||
pub const DEFAULT_MIN_STACK_SIZE: usize = 1024 * 1024;
|
||||
|
||||
pub struct Thread {
|
||||
id: libc::pthread_t,
|
||||
|
|
@ -25,18 +21,11 @@ unsafe impl Sync for Thread {}
|
|||
|
||||
// The pthread_attr_setstacksize symbol doesn't exist in the emscripten libc,
|
||||
// so we have to not link to it to satisfy emcc's ERROR_ON_UNDEFINED_SYMBOLS.
|
||||
#[cfg(not(target_os = "emscripten"))]
|
||||
unsafe fn pthread_attr_setstacksize(attr: *mut libc::pthread_attr_t,
|
||||
stack_size: libc::size_t) -> libc::c_int {
|
||||
libc::pthread_attr_setstacksize(attr, stack_size)
|
||||
}
|
||||
|
||||
#[cfg(target_os = "emscripten")]
|
||||
unsafe fn pthread_attr_setstacksize(_attr: *mut libc::pthread_attr_t,
|
||||
_stack_size: libc::size_t) -> libc::c_int {
|
||||
panic!()
|
||||
}
|
||||
|
||||
impl Thread {
|
||||
// unsafe: see thread::Builder::spawn_unchecked for safety requirements
|
||||
pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>)
|
||||
|
|
@ -149,31 +138,6 @@ pub mod guard {
|
|||
pub unsafe fn deinit() {}
|
||||
}
|
||||
|
||||
// glibc >= 2.15 has a __pthread_get_minstack() function that returns
|
||||
// PTHREAD_STACK_MIN plus however many bytes are needed for thread-local
|
||||
// storage. We need that information to avoid blowing up when a small stack
|
||||
// is created in an application with big thread-local storage requirements.
|
||||
// See #6233 for rationale and details.
|
||||
#[cfg(target_os = "linux")]
|
||||
#[allow(deprecated)]
|
||||
fn min_stack_size(attr: *const libc::pthread_attr_t) -> usize {
|
||||
weak!(fn __pthread_get_minstack(*const libc::pthread_attr_t) -> libc::size_t);
|
||||
|
||||
match __pthread_get_minstack.get() {
|
||||
None => libc::PTHREAD_STACK_MIN,
|
||||
Some(f) => unsafe { f(attr) },
|
||||
}
|
||||
}
|
||||
|
||||
// No point in looking up __pthread_get_minstack() on non-glibc
|
||||
// platforms.
|
||||
#[cfg(all(not(target_os = "linux"),
|
||||
not(target_os = "netbsd")))]
|
||||
fn min_stack_size(_: *const libc::pthread_attr_t) -> usize {
|
||||
libc::PTHREAD_STACK_MIN
|
||||
}
|
||||
|
||||
#[cfg(target_os = "netbsd")]
|
||||
fn min_stack_size(_: *const libc::pthread_attr_t) -> usize {
|
||||
2048 // just a guess
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue